<template>
  <div style="width: 100%; height: 100%">
    <div
      id="MAPContainer"
      :class="{
        MAPContainer_building: $route.name == 'BuildingModelDetails',
        MAPContainer_black: !isGlobe && $route.name != 'BuildingModelDetails',
      }"
      @mouseenter="MAPContainer_mouseenter"
      @mouseleave="MAPContainer_mouseleave"
    >
      <cesium-map-popup
        ref="cesiumMapPopup"
        :mapPopupData="mapPopupData"
        :mapPopupStyle="mapPopupStyle"
        @editClusterData="editClusterData"
      >
      </cesium-map-popup>
      <floor-popup
        ref="floorPopup"
        :floorPopupData="floorPopupData"
        :floorPopupStyle="floorPopupStyle"
      ></floor-popup>
      <cesium-map-tooltip
        ref="cesiumMapTooltip"
        :mapTooltipData="mapTooltipData"
        :mapTooltipStyle="mapTooltipStyle"
      >
      </cesium-map-tooltip>
    </div>
    <cesium-map-legend
      v-show="$route.name != 'BuildingModelDetails'"
      ref="cesiumMapLegend"
      :tilesetStyle="tilesetStyle"
      @openOrClosePopup="$refs.cesiumMapPopup.openOrClosePopup($event)"
    ></cesium-map-legend>
    <cesium-map-grid-legend
      v-show="$route.name != 'BuildingModelDetails'"
      ref="cesiumMapGridLegend"
    ></cesium-map-grid-legend>
    <!-- 楼层详情弹窗 -->
    <transition name="el-zoom-in-center">
      <floor-details ref="floorDetails"></floor-details>
    </transition>
  </div>
</template>

<script>
import { AtomSpinner } from "epic-spinners";
import mapImagery from "@/assets/js/map/mapImagery.js";
require("@/utils/mapImageryTool/index");
import CesiumMapPopup from "./CesiumMapPopup.vue";
import FloorPopup from "../modules/FloorPopup.vue";
import CesiumMapTooltip from "./CesiumMapTooltip.vue";
import CesiumMapLegend from "./CesiumMapLegend.vue";
import CesiumMapGridLegend from "./CesiumMapGridLegend.vue";
import FloorDetails from "@/components/modules/FloorDetails.vue";
import DynamicRange from "@/assets/js/map/dynamicRange.js";
import WallRegularDiffuse from "@/assets/js/map/wallRegularDiffuse.js";
import rotateMaterial from "@/assets/js/map/rotateMaterial.js";
import radarSolidScan from "@/assets/js/map/radarSolidScan.js";
import tilesetKey from "@/assets/js/map/tilesetKey.js";
// import grid from "@/assets/js/map/grid.js";
import czml from "@/assets/js/map/czml.js";
import { bearing, setRoamViewFunction } from "@/assets/js/map/Angle.js";
import ClusterLayer from "@/assets/js/map/ClusterLayer.js";
import ClusterLayer2 from "@/assets/js/map/ClusterLayer2.js";

// Cesium Cartesian3 和经纬度以及屏幕坐标等之间的转换
// https://blog.csdn.net/u013821237/article/details/80169327

export default {
  name: "CesiumMap",
  components: {
    "cesium-map-popup": CesiumMapPopup,
    "floor-popup": FloorPopup,
    "cesium-map-tooltip": CesiumMapTooltip,
    "cesium-map-legend": CesiumMapLegend,
    "cesium-map-grid-legend": CesiumMapGridLegend,
    "floor-details": FloorDetails,
    "atom-spinner": AtomSpinner,
  },
  data() {
    return {
      loading: false,
      loadingText: "加载中...",

      MOUSE_MOVE_DISABLED: false,

      isCluster: true, // 是否采用聚合点

      tilesetStyle: "", // 3D瓦片集风格

      // 临时记录标绘的显示隐藏状态
      plotStatus: null,

      // 地球视角
      earthView: {
        position: {
          x: -6129033.324541072,
          y: 21268181.15169482,
          z: 14477278.256889585,
        },
        heading: 0.0,
        pitch: -88.17,
        roll: 0.0,
      },
      // 南宁地图视角
      nanningView: {
        position: {
          x: -1878370.2584966116,
          y: 5656990.614273708,
          z: 2400600.8975878134,
        },
        heading: 0.0,
        pitch: -28.66,
        roll: 0.0,
      },
      // 网格地图视角
      gridView: {
        position: {
          x: -1852024.7659239627,
          y: 5583590.445956534,
          z: 2458274.6257418715,
        },
        heading: 0.0,
        pitch: -82.04,
        roll: 0.0,
      },
      // 小区介绍牌子的最佳视野
      areaIntroView: {
        position: {
          x: -1851966.6059893614,
          y: 5583559.263938658,
          z: 2457501.3054035623,
        },
        heading: 0.0,
        pitch: -28.66,
        roll: 0.0,
      },
      // 切换的最佳视野
      bestViews: [
        // 小区-前视角
        {
          position: {
            x: -1851935.4847664698,
            y: 5583570.457541069,
            z: 2457499.325658619,
          },
          heading: 0.0,
          pitch: -28.66,
          roll: 0.0,
        },
        // 小区-右视角
        {
          position: {
            x: -1852504.0516127527,
            y: 5583188.75104946,
            z: 2458315.437108071,
          },
          heading: 269.79,
          pitch: -41.58,
          roll: 0.0,
        },
        // 小区-后视角
        {
          position: {
            x: -1851816.8328622952,
            y: 5583236.513248765,
            z: 2459012.368246226,
          },
          heading: 178.44,
          pitch: -40.22,
          roll: 0.0,
        },
        // 小区-左视角
        {
          position: {
            x: -1851170.5202940588,
            y: 5583571.103016622,
            z: 2458273.123527746,
          },
          heading: 88.53,
          pitch: -34.1,
          roll: 0.0,
        },
        // 小区-俯视角
        {
          position: {
            x: -1852089.785894481,
            y: 5583995.771620917,
            z: 2457284.564158385,
          },
          heading: 0.0,
          pitch: -28.66,
          roll: 0.0,
        },
      ],
      bestViewsIndex: -1,

      // 飞往主页
      homeFlyOptions: {
        duration: 3,
        offset: {
          heading: 0.0, // 方向
          pitch: -28.66, // 倾斜角度
          range: 800,
        },
      },
      // 飞往某一楼栋处
      buildingFlyOptions: {
        duration: 2,
        offset: {
          heading: 2.64, // 方向
          pitch: -16.76, // 倾斜角度
          range: 80,
        },
      },
      buildingFlyOptions2: {
        duration: 2,
        offset: {
          heading: 2.64, // 方向
          pitch: -30.0, // 倾斜角度
          range: 120,
        },
      },
      // 飞往某一绘标（点、线、面、图标等）处
      plotFlyOptions: {
        duration: 2,
        offset: {
          heading: 1.37, // 方向
          pitch: -53.18, // 倾斜角度
          range: 50,
        },
      },
      // 飞往瓦片集处
      tilesetFlyOptions: {
        duration: 2,
        offset: {
          heading: 0.0, // 方向
          pitch: -28.65, // 倾斜角度
          range: 900,
        },
      },

      // 楼栋模型的颜色
      colors: [
        { r: 65, g: 42, b: 255, a: 1 }, // rgba(65, 42, 255, 1),
        { r: 85, g: 104, b: 255, a: 1 }, // rgba(85, 104, 255, 1),
        { r: 93, g: 129, b: 255, a: 1 }, // rgba(93, 129, 255, 1),
        { r: 101, g: 155, b: 255, a: 1 }, // rgba(101, 155, 255, 1),
        { r: 109, g: 177, b: 255, a: 1 }, // rgba(109, 177, 255, 1),
        { r: 115, g: 199, b: 255, a: 1 }, // rgba(115, 199, 255, 1),
        { r: 121, g: 217, b: 255, a: 1 }, // rgba(121, 217, 255, 1),
        { r: 56, g: 205, b: 236, a: 1 }, // rgba(56, 205, 236, 1),
        { r: 64, g: 221, b: 244, a: 1 }, // rgba(64, 221, 244, 1),
        { r: 70, g: 235, b: 251, a: 1 }, // rgba(70, 235, 251, 1),
      ],
      // 楼栋模型的激活颜色
      activeBuildingColor: { r: 144, g: 255, b: 0, a: 1 }, // rgba(144, 255, 0, 1)
      // 楼栋模型的轮廓（边框）颜色
      silhouetteColor: { r: 61, g: 30, b: 255, a: 1 }, // rgba(61, 30, 255, 1)

      // 定义点、线、面、模型等与相机的距离，显示在距相机的距离在多少区间内是可以显示的
      distanceDisplayCondition: [1, 1200],
      // 定义label与相机的距离，显示在距相机的距离在多少区间内是可以显示的
      distanceDisplayConditionLabel: [1, 300],
      // 定义小区展示牌与相机的距离，显示在距相机的距离在多少区间内是可以显示的
      distanceDisplayCondition2: [1200, 10000],

      // 信息窗
      mapPopupData: null, // 必须包含name（标题）、type（弹窗类型）、id（唯一标识）等字段
      mapPopupStyle: {
        width: "392px",
        height: "164px",
        left: "0px",
        top: "0px",
      },

      // 楼层信息窗
      floorPopupData: null,
      floorPopupStyle: {
        left: "0px",
        top: "0px",
      },

      // 提示框
      mapTooltipData: null, // 必须包含name（标题）、type（弹窗类型）等字段
      mapTooltipStyle: {
        left: "0px",
        top: "0px",
      },

      isGlobe: true, // 是否显示地球
    };
  },
  props: {},
  watch: {
    $route(newV, oldV) {
      let self = this;
      console.log("watch", newV.name, oldV.name);
      let viewer = window.vmCesiumViewer;
      if (!viewer) {
        return;
      }
      if (
        newV &&
        (newV.name == "Login" ||
          newV.name == "Error" ||
          newV.name == "BuildingModelDetails")
      ) {
        return;
      }
      // 切换主菜单时
      if (newV && newV.name && oldV.name != "BuildingModelDetails") {
        // 显示或者隐藏左右两侧信息面板
        self.$store.commit(
          "common_store_fun",
          (e) =>
            (e.leftOrRightBox = {
              left: true,
              right: true,
            })
        );
        // 关闭信息窗和提示框
        self.closeAllPopup();
        // 显示地球
        viewer.scene.globe.show = true;
        self.isGlobe = true;

        // 销毁热力图
        self.$refs.cesiumMapLegend.delete_chart();

        // 当页面为首页时，设置为地球
        if (newV.name == "Home") {
          self.setView_earth(viewer, true);
        } else {
          self.setView_area(viewer);
        }
        // 给 plotStatus 赋值
        self.initPlotStatus(newV.name);
        // 根据 plotStatus 缓存记录的状态，正确显示隐藏标绘
        self.byPloatStatusHideOrShow();
      }
      // 从楼栋详情页面返回时
      if (newV && newV.name && oldV.name == "BuildingModelDetails") {
        // 关闭信息窗和提示框
        self.closeAllPopup();
        // 显示地球
        viewer.scene.globe.show = true;
        self.isGlobe = true;
        // 标绘
        // let is = self.$refs.cesiumMapLegend.isShowMapPopup;
        let is = true;
        self.isShowPlotTypeEntities(viewer.entities.values, is, "polygon"); // 显示标绘- 面
        self.isShowPlotTypeEntities(viewer.entities.values, is, "billboard"); // 显示标绘- 图标
        self.isShowPlotTypeEntities(viewer.entities.values, is, "label"); // 显示标绘- label
        self.isShowPlotTypeEntities(viewer.entities.values, is, "title"); // 显示标绘- title
        self.isShowPlotTypeEntities(
          viewer.entities.values,
          is,
          "communityWall"
        ); // 显示标绘- 小区墙
        self.isShowPlotTypeEntities(viewer.entities.values, is, "polyline"); // 显示标绘- 线 communityMiddle
        self.isShowPlotTypeEntities(viewer.entities.values, is, "dot"); // 显示标绘- 点 communityBottom
        // 根据 plotStatus 缓存记录的状态，正确显示隐藏标绘
        self.byPloatStatusHideOrShow();
        // 如果为真，则允许用户旋转相机。如果为假，相机将锁定到当前标题。此标志仅适用于2D和3D。
        viewer.scene.screenSpaceCameraController.enableRotate = true;
        // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
        viewer.scene.screenSpaceCameraController.enableTranslate = true;
        // 如果为真，允许用户放大和缩小。如果为假，相机将锁定到距离椭圆体的当前距离
        viewer.scene.screenSpaceCameraController.enableZoom = true;
        // 如果为真，则允许用户倾斜相机。如果为假，相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
        viewer.scene.screenSpaceCameraController.enableTilt = true;
        self.setView_area(viewer); // 设置为小区视野
        self.isShowTileset(
          self.tilesetStyle == "新竹-科技风格"
            ? CesiumGlobeData.vueTileset1
            : CesiumGlobeData.vueTileset2,
          true
        ); // 显示3Dtileset
        self.removeModel(viewer); // 清除原来的模型
      }
    },
  },
  created() {
    this.returnMarkers();
  },
  mounted() {
    this.init(this.$route.name);
    this.registerEventBus();
  },
  beforeDestroy() {
    this.destroyEventBus();
  },
  destroyed() {
    this.destroyMap();
  },
  methods: {
    /** 打开地图 */
    open_map() {
      // 关闭信息窗和提示框
      this.closeAllPopup();
      // 显示地球
      window.vmCesiumViewer.scene.globe.show = true;
      this.isGlobe = true;
    },
    /** 关闭热力图，恢复到原先该菜单下的图标显示情况，并调整视角到小区 */
    recover() {
      let self = this;
      let viewer = window.vmCesiumViewer;
      // 关闭信息窗和提示框
      self.closeAllPopup();
      // 显示地球
      viewer.scene.globe.show = true;
      self.isGlobe = true;
      // 当页面为首页时，设置为地球
      if (this.$route.name == "Home") {
        // self.setView_earth(viewer, true);
        self.setView_area(viewer);
      } else {
        self.setView_area(viewer);
      }
      // 给 plotStatus 赋值
      // self.initPlotStatus(this.$route.name);
      // 根据 plotStatus 缓存记录的状态，正确显示隐藏标绘
      self.byPloatStatusHideOrShow();
    },
    /**
     * 注册eventbus
     */
    registerEventBus() {
      let self = this;
      this.$bus.$on("initMapEvent", function () {
        self.initMap();
      });
      this.$bus.$on("destroyMapEvent", function () {
        self.destroyMap();
      });
      this.$bus.$on("skipBuildingDetailsEvent", function (query) {
        self.skipBuildingDetails(query);
      });
      this.$bus.$on("dbclickBuildingEvent", function (data) {
        self.dbclickBuilding(data);
      });
      this.$bus.$on("locationBillboardEvent", function (type, id) {
        self.locationBillboard(type, id, true);
      });
      this.$bus.$on(
        "precisePositioningEvent",
        function (number, floor, unit, room, status) {
          self.precisePositioning(number, floor, unit, room, status);
        }
      );
      this.$bus.$on("closeGrid", function () {
        self.$refs.cesiumMapGridLegend.setCheckedCities([]); // 清空网格图例的checkbox
      });
      this.$bus.$on("getTilesetStyle", function (bool) {
        if (self.tilesetStyle == "新竹-科技风格")
          CesiumGlobeData.vueTileset1.show = bool;
        else CesiumGlobeData.vueTileset2.show = bool;
      });
    },
    /**
     * 销毁eventbus
     */
    destroyEventBus() {
      this.$bus.$off("initMapEvent");
      this.$bus.$off("destroyMapEvent");
      this.$bus.$off("skipBuildingDetailsEvent");
      this.$bus.$off("dbclickBuildingEvent");
      this.$bus.$off("locationBillboardEvent");
      this.$bus.$off("precisePositioningEvent");
      this.$bus.$off("closeGrid");
      this.$bus.$off("getTilesetStyle");
    },
    // ====================【eventbus 事件处理程序 start】==========================
    /** 初始化地图 this.$bus.$emit('initMapEvent') */
    initMap() {
      this.init(this.$route.name);
    },
    /** 销毁地图 this.$bus.$emit('destroyMapEvent') */
    destroyMap() {
      const viewer = window.vmCesiumViewer;
      if (viewer) {
        viewer.dataSources.removeAll(true);
        viewer.scene.primitives.removeAll();
        viewer.entities.removeAll();
        viewer.imageryLayers.removeAll();
        viewer.destroy();
      }
    },
    /**
     * 前往楼栋详情
     * this.$bus.$emit('skipBuildingDetailsEvent', query)
     */
    skipBuildingDetails(query) {
      let self = this;
      // 只查看新竹小区的楼栋，其他的不查看
      if (query.number && query.number.includes("栋")) {
        // 关闭信息窗和提示框
        self.closeAllPopup();
        // 隐藏3Dtileset
        self.isShowTileset(
          self.tilesetStyle == "新竹-科技风格"
            ? CesiumGlobeData.vueTileset1
            : CesiumGlobeData.vueTileset2,
          false
        );
        // 渲染楼栋的模型
        self.renderBuildingModel(window.vmCesiumViewer, query, 0.0);
        // 跳转楼栋Model详情页面
        self.$router.push({
          name: "BuildingModelDetails",
          query: query,
        });
      } else {
        self.$message.info(
          "【" +
            query.number +
            "】" +
            "不是新竹小区所属楼栋，无法查看相关信息！"
        );
      }
    },
    /**
     * 双击楼栋列表，打开标题提示框以及拉近视野
     * this.$bus.$emit('dbclickBuildingEvent', data)
     */
    dbclickBuilding(data) {
      let self = this;
      let buildingInfo = {
        pick: null,
        id: data.mc,
        name: data.mc,
        featureId: 0, // Tile拾取的featureId
        number: data.mc, // 楼栋编号
        height: data.lg, // 楼栋总高度
        floorHeigth: data.lg / data.lcs, // 楼栋各楼层的高度
        floorTotal: data.lcs, // 楼栋楼层总数量
        position: {
          lng: data.jd,
          lat: data.wd,
          height: 0,
        }, // 楼栋的中心点
        positions: [], // 楼栋的polygon
      };

      let viewer = window.vmCesiumViewer;

      // 如果楼栋有轮廓线，清除
      if (CesiumGlobeData.houetteStage) {
        viewer.scene.postProcessStages.remove(CesiumGlobeData.houetteStage);
        CesiumGlobeData.houetteStage = null;
      }
      // 如果楼栋有feature
      let previousPickedEntity = CesiumGlobeData.previousPickedEntity;
      if (previousPickedEntity.feature != undefined) {
        // 还原以前选择要素的原本颜色
        previousPickedEntity.feature.color = previousPickedEntity.originalColor;
        // 将previousPickedEntity_3DTileFeature的属性设置为undefined
        previousPickedEntity.feature = undefined;
        previousPickedEntity.originalColor = undefined;
      }

      // 创建楼栋定位点
      CesiumGlobeData.vueLocationPoint = self.createLocationPoint(
        viewer,
        {
          lng: buildingInfo.position.lng,
          lat: buildingInfo.position.lat,
          height: 0,
        },
        buildingInfo.height,
        buildingInfo.number
      );
      // 飞往该楼栋处 (通过楼栋定位点)
      self.viewerFlyTo(
        viewer,
        CesiumGlobeData.vueLocationPoint,
        {
          duration: self.buildingFlyOptions2.duration,
          offset: {
            heading: Cesium.Math.toRadians(
              self.buildingFlyOptions2.offset.heading
            ), // 方向
            pitch: Cesium.Math.toRadians(self.buildingFlyOptions2.offset.pitch), // 倾斜角度
            range: self.buildingFlyOptions2.offset.range,
          },
        }
        // 20
        // 15
      );

      self.openTooltip(
        viewer,
        {
          gisPosition: Cesium.Cartesian3.fromDegrees(
            buildingInfo.position.lng,
            buildingInfo.position.lat,
            buildingInfo.height
          ),
          apiData: buildingInfo,
        },
        "building",
        buildingInfo.number
      );
    },
    /**
     * 定位到化粪池、摄像头以及各设备
     * this.$bus.$emit('locationBillboardEvent', type, id)
     */
    locationBillboard(
      type,
      id,
      viewerFly_bool = true,
      clusterArray = undefined,
      clusterIndex = 0
    ) {
      // console.log(type, id)
      let self = this;
      let viewer = window.vmCesiumViewer;
      let entity = self.getEntityById(viewer, "billboard", type, id);
      entity.show = true;
      // console.log(entity)
      if (entity === undefined) {
        this.$message.info("没有该点位！");
        return;
      }
      self.activetEntity(viewer, "billboard", type, id);
      if (type == "community" || type == "grid") {
        self.activetEntity(viewer, "polygon", "community", id); // 特殊处理：小区\网格polygon
      }

      if (
        entity.properties.popupConfig._value.height != 0 &&
        entity.properties.popupConfig._value.width != 0
      ) {
        self.openPopup(
          viewer,
          "billboard",
          type,
          id,
          clusterArray,
          clusterIndex
        );
      }

      if (viewerFly_bool)
        self.viewerFlyTo(
          viewer,
          entity,
          {
            duration: self.plotFlyOptions.duration,
            offset: {
              heading: Cesium.Math.toRadians(
                self.plotFlyOptions.offset.heading
              ), // 方向
              pitch: Cesium.Math.toRadians(self.plotFlyOptions.offset.pitch), // 倾斜角度
              range: self.plotFlyOptions.offset.range,
            },
          },
          // entity.properties.popupConfig._value.height / 1.6
          90
        );
    },
    /**
     * 精准定位到某一楼层、某一单元、某一楼层
     * this.$bus.$emit('precisePositioningEvent', number, floor, unit, room, status)
     */
    precisePositioning(number, floor, unit, room, status) {
      this.$refs.floorDetails.openOrClose(true);
      this.$refs.floorDetails.setActiveFloor(Number(floor));
      this.$refs.floorDetails.setCurrentUnit(unit);
      this.$refs.floorDetails.setActiveRoom(room);
      this.$refs.floorDetails.setStatusRoom(status);
      this.$refs.floorDetails.setNumber(number);
    },
    // ====================【eventbus 事件处理程序 end】==========================

    /**
     * 初始化
     */
    init(routeName) {
      if (routeName == "Home") {
        this.bestViewsIndex = -1;
      } else {
        this.bestViewsIndex = 0;
      }
      // 给 plotStatus 赋值
      this.initPlotStatus(routeName);
      // 初始化Cesium
      this.initCesium();
    },
    // 给 plotStatus 赋值
    initPlotStatus(routeName) {
      let self = this;
      self.plotStatus = CesiumGlobeData["plotStatus" + routeName];
      return;
      if (self.$refs.cesiumMapLegend.isShowMapPopup) {
        self.plotStatus = CesiumGlobeData["plotStatus" + routeName];
      } else {
        self.plotStatus = {
          septicTank: "hide",
          monitoring: "hide",
          antiepidemic: "hide",
          // community: 'hide',
          gate: "hide",
          fireHydrant: "hide",
          entrance: "hide",
          communityWall:
            CesiumGlobeData["plotStatus" + routeName].communityWall,
          grid: CesiumGlobeData["plotStatus" + routeName].grid,
        };
      }
    },
    /**
     * 初始化Cesium
     */
    initCesium() {
      let self = this;

      const cesiumContainerId = CesiumGlobeConfig.cesiumContainerId;
      const loadingIndicatorId = CesiumGlobeConfig.loadingIndicatorId;
      const opt = CesiumGlobeConfig.opt;
      const mapImageData = CesiumGlobeConfig.mapImageData

      new CesiumGlobe().init(
        cesiumContainerId,
        loadingIndicatorId,
        opt,
        function (viewer) {
          // cesium 其它设置
          new CesiumGlobe().otherSettings(viewer, opt, self);
          // 影像图层
          new CesiumGlobe().imageryFunction(
            viewer,
            mapImagery,
            mapImageData,
            self
          );
          // 事件监听
          self.eventListener(viewer);
          // 事件交互
          self.eventInteraction(viewer);
        },
        self
      );
    },

    /**
     * 关闭信息窗和提示框
     */
    closeAllPopup() {
      let self = this;
      self.$refs.cesiumMapTooltip
        ? self.$refs.cesiumMapTooltip.openOrCloseTooltip(false)
        : "";
      self.$refs.floorPopup
        ? self.$refs.floorPopup.openOrCloseFloorPopup(false)
        : "";
      self.$refs.cesiumMapPopup
        ? self.$refs.cesiumMapPopup.openOrClosePopup(false)
        : "";
    },

    /**
     * 设置位置
     */
    // 地球视角
    setView_earth(viewer, isAuto) {
      let self = this;

      // 显示地球
      viewer.scene.globe.show = true;
      self.isGlobe = true;

      // 创建主页的定位点
      // CesiumGlobeData.vueLocationPoint = self.createLocationPoint(
      //   viewer,
      //   {
      //     lng: 108.349596,
      //     lat: 22.816989,
      //     height: 0,
      //   },
      //   0,
      //   "主页"
      // );

      self.bestViewsIndex = -1;
      // flyTo
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.earthView.position.x,
          self.earthView.position.y,
          self.earthView.position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(self.earthView.heading),
          pitch: Cesium.Math.toRadians(self.earthView.pitch),
          roll: self.earthView.roll,
        },
        duration: 3, // 飞行持续时间（以秒为单位）。如果省略，Cesium会尝试根据航班飞行的距离来计算理想持续时间。
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
        complete: function () {
          // 到达位置后执行的回调函数
          isAuto ? self.setView_area(viewer) : "";
          // if (isAuto) {
          //   self.bestViewsIndex = 0;
          //   // 飞往该主页处 (通过主页定位点)
          //   self.viewerFlyTo(
          //     viewer,
          //     CesiumGlobeData.vueLocationPoint,
          //     {
          //       duration: self.homeFlyOptions.duration,
          //       offset: {
          //         heading: Cesium.Math.toRadians(
          //           self.homeFlyOptions.offset.heading
          //         ), // 方向
          //         pitch: Cesium.Math.toRadians(
          //           self.homeFlyOptions.offset.pitch
          //         ), // 倾斜角度
          //         range: self.homeFlyOptions.offset.range,
          //       },
          //     },
          //     null
          //     // 15
          //   );
          // }
        },
        pitchAdjustHeight: -90, // 如果摄像机飞越高于该值，则调整俯仰俯仰的俯仰角度，并将地球保持在视口中。
        maximumHeight: 5000, // 相机最大飞行高度
        // flyOverLongitude:100, // 如果到达目的地有2种方式，设置具体值后会强制选择方向飞过这个经度(这个，很好用)
      });
    },
    // 南宁视角
    setView_nanning(viewer) {
      let self = this;
      self.bestViewsIndex = -1;
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.nanningView.position.x,
          self.nanningView.position.y,
          self.nanningView.position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(self.nanningView.heading),
          pitch: Cesium.Math.toRadians(self.nanningView.pitch),
          roll: self.nanningView.roll,
        },
        duration: 3,
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
      });
    },
    // 网格视角
    setView_gird(viewer) {
      let self = this;
      // 关闭信息窗和提示框
      self.closeAllPopup();
      // 显示所有网格
      self.$refs.cesiumMapGridLegend.setCheckedCities([
        "1",
        "2",
        "3",
        "4",
        "5",
      ]);
      // 隐藏所有标绘
      self.$refs.cesiumMapLegend.showOrHidePopup(false);
      // 隐藏小区围墙
      self.$refs.cesiumMapLegend.legendClick("communityWall", "hide");
      // 隐藏地球
      viewer.scene.globe.show = false;
      self.isGlobe = false;
      self.bestViewsIndex = -2;
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.gridView.position.x,
          self.gridView.position.y,
          self.gridView.position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(self.gridView.heading),
          pitch: Cesium.Math.toRadians(self.gridView.pitch),
          roll: self.gridView.roll,
        },
        duration: 3,
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
        complete: function () {
          // self.$bus.$emit("showOrHidePopup", false);
          // 隐藏左右两侧信息面板
          self.$store.commit(
            "common_store_fun",
            (e) =>
              (e.leftOrRightBox = {
                left: false,
                right: false,
              })
          );
        },
      });
    },
    // 小区-前视角
    setView_area(viewer) {
      let self = this;
      self.bestViewsIndex = 0;
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.bestViews[0].position.x,
          self.bestViews[0].position.y,
          self.bestViews[0].position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(self.bestViews[0].heading),
          pitch: Cesium.Math.toRadians(self.bestViews[0].pitch),
          roll: self.bestViews[0].roll,
        },
        duration: 3,
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
      });
    },
    // 小区-俯视角
    setView_area2(viewer) {
      let self = this;
      self.bestViewsIndex = 4;
      self.$refs.cesiumMapPopup.openOrClosePopup(false);
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.bestViews[4].position.x,
          self.bestViews[4].position.y,
          self.bestViews[4].position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(self.bestViews[4].heading),
          pitch: Cesium.Math.toRadians(self.bestViews[4].pitch),
          roll: self.bestViews[4].roll,
        },
        duration: 3,
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
        complete: function () {
          // 到达位置后执行的回调函数
          self.bestViewsIndex = 0;
          viewer.camera.flyTo({
            destination: new Cesium.Cartesian3(
              self.areaIntroView.position.x,
              self.areaIntroView.position.y,
              self.areaIntroView.position.z
            ),
            orientation: {
              heading: Cesium.Math.toRadians(self.areaIntroView.heading),
              pitch: Cesium.Math.toRadians(self.areaIntroView.pitch),
              roll: self.areaIntroView.roll,
            },
            duration: 3,
            easingFunction: Cesium.EasingFunction.LINEAR_NONE,
            complete: function () {
              // self.$bus.$emit("showOrHidePopup", false);
              // 隐藏左右两侧信息面板
              self.$store.commit(
                "common_store_fun",
                (e) =>
                  (e.leftOrRightBox = {
                    left: false,
                    right: false,
                  })
              );
              self.locationBillboard("communityTop", 1, false);
            },
          });
        },
      });
    },
    // 切换视角
    setViews(viewer) {
      let self = this;
      self.bestViewsIndex++;
      if (
        self.bestViewsIndex >= self.bestViews.length ||
        self.bestViewsIndex < 0
      ) {
        self.bestViewsIndex = 0;
      }
      viewer.camera.flyTo({
        destination: new Cesium.Cartesian3(
          self.bestViews[self.bestViewsIndex].position.x,
          self.bestViews[self.bestViewsIndex].position.y,
          self.bestViews[self.bestViewsIndex].position.z
        ),
        orientation: {
          heading: Cesium.Math.toRadians(
            self.bestViews[self.bestViewsIndex].heading
          ),
          pitch: Cesium.Math.toRadians(
            self.bestViews[self.bestViewsIndex].pitch
          ),
          roll: self.bestViews[self.bestViewsIndex].roll,
        },
        duration: 3,
        easingFunction: Cesium.EasingFunction.LINEAR_NONE,
      });
    },

    // 根据 plotStatus 临时缓存记录的状态，正确显示隐藏标绘
    byPloatStatusHideOrShow() {
      let self = this;
      if (self.plotStatus) {
        let object = self.plotStatus;
        for (const key in object) {
          if (Object.hasOwnProperty.call(object, key)) {
            const element = object[key];
            if (key != "grid") {
              self.$refs.cesiumMapLegend.legendClick(key, element);
            } else {
              self.$refs.cesiumMapGridLegend.setCheckedCities(element);
            }
          }
        }
      }
    },

    /**
     * 事件监听
     */
    eventListener(viewer) {
      let self = this;
      // 标绘
      self.entityFunction(viewer);
      // 当页面为楼栋Model详情时，加载模型
      if (self.$route.name == "BuildingModelDetails") {
        let query = self.$route.query;
        if (
          query.hasOwnProperty("number") &&
          query.hasOwnProperty("height") &&
          query.hasOwnProperty("floorHeigth") &&
          query.hasOwnProperty("floorTotal") &&
          query.hasOwnProperty("lng") &&
          query.hasOwnProperty("lat")
        ) {
          // 渲染楼栋的模型
          self.renderBuildingModel(viewer, query, 1.0);
        }
      }
      // 当页面为首页时，设置为地球
      if (self.$route.name == "Home") {
        setTimeout(() => {
          self.setView_earth(viewer, true);
        }, 500);
      }
    },

    /**
     * 事件交互
     * https://cesium.com/learn/cesiumjs/ref-doc/global.html?classFilter=ScreenSpaceEventType#ScreenSpaceEventType
     * ScreenSpaceEventType、event
     */
    eventInteraction(viewer) {
      // 记录原来选择的要素
      var previousPickedEntity = {
        feature: undefined,
        originalColor: undefined,
      };
      CesiumGlobeData.previousPickedEntity = previousPickedEntity;
      var previousPickedClassPrimitive = {
        feature: undefined,
        originalColor: undefined,
      };
      var previousPickedModel = {
        feature: undefined,
        originalColor: undefined,
      };

      // 移动
      handler.setInputAction(function (event) {
        // 如果有单一tile的轮廓高亮，移入其它地方先行取消
        if (
          CesiumGlobeData.silhouette &&
          CesiumGlobeData.silhouette.selected &&
          CesiumGlobeData.silhouette.selected.length > 0
        ) {
          CesiumGlobeData.silhouette.selected = [];
        }

        if (Cesium.defined(pick)) {
          // 判断选择是否为Cesium3DTileFeature，即3D瓦片集（3D楼栋建筑）
          if (pick instanceof Cesium.Cesium3DTileFeature) {
            // console.log("选中了3D楼栋建筑：", pick);
            // 判断以前是否选择该要素
            let TILESETNAME = decodeURIComponent(
              pick.content.url.split("/static/tileset/")[1].split("/")[0]
            );
            if (
              pick != previousPickedEntity.feature &&
              TILESETNAME == "新竹-科技风格"
            ) {
              if (previousPickedEntity.feature != undefined) {
                // 还原以前选择要素的原本颜色
                previousPickedEntity.feature.color =
                  previousPickedEntity.originalColor;
                // 将当前选择要素及其颜色添加到previousPickedEntity_3DTileFeature
                previousPickedEntity.feature = pick;
                previousPickedEntity.originalColor = pick.color;
              }
              // 将当前选择要素及其颜色添加到previousPickedEntity_3DTileFeature
              previousPickedEntity.feature = pick;
              previousPickedEntity.originalColor = pick.color;
            }
            // 将模型变为黄色高亮
            TILESETNAME == "新竹-科技风格"
              ? (pick.color = Cesium.Color.KHAKI)
              : null;

            // 移入时，单一tile轮廓高亮
            if (CesiumGlobeData.houetteStage) {
              viewer.scene.postProcessStages.remove(
                CesiumGlobeData.houetteStage
              );
              CesiumGlobeData.houetteStage = null;
            }
            CesiumGlobeData.silhouette =
              Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
            CesiumGlobeData.silhouette.uniforms.color = new Cesium.Color(
              255 / 255,
              114 / 255,
              0,
              1
            );
            CesiumGlobeData.silhouette.uniforms.length = 0.02;
            CesiumGlobeData.silhouette.selected = [pick]; // 点选效果
            CesiumGlobeData.houetteStage =
              Cesium.PostProcessStageLibrary.createSilhouetteStage([
                CesiumGlobeData.silhouette,
              ]);
            viewer.scene.postProcessStages.add(CesiumGlobeData.houetteStage);

            let buildingInfo = self.returnBuildingInfo(
              viewer,
              pick,
              event.endPosition
            );
            self.openTooltip(
              viewer,
              {
                gisPosition: Cesium.Cartesian3.fromDegrees(
                  buildingInfo.position.lng,
                  buildingInfo.position.lat,
                  buildingInfo.height
                ),
                // gisPosition: viewer.scene.globe.pick(
                //   viewer.camera.getPickRay(event.endPosition),
                //   viewer.scene
                // ),
                apiData: buildingInfo,
              },
              "building",
              buildingInfo.number
            );
          } else {
            // console.log("没有选中3D楼栋建筑！！！");
            self.$refs.cesiumMapTooltip.openOrCloseTooltip(false);
            if (previousPickedEntity.feature != undefined) {
              // 还原以前选择要素的原本颜色
              previousPickedEntity.feature.color =
                previousPickedEntity.originalColor;
              // 将previousPickedEntity_3DTileFeature的属性设置为undefined
              previousPickedEntity.feature = undefined;
              previousPickedEntity.originalColor = undefined;
            }
          }

          // 判断选择是否为ClassificationPrimitive，即楼栋分层、单体化
          if (
            pick.hasOwnProperty("id") &&
            pick.primitive &&
            pick.primitive instanceof Cesium.ClassificationPrimitive
          ) {
            // console.log("选中了楼层：", pick);
            let name = pick.id
              .split("polygonClassificationPrimitive_")[1]
              .split("_")[0];
            let id = pick.id
              .split("polygonClassificationPrimitive_")[1]
              .split("_")[1];
            let index = Number(id) - 1;
            const attributes = pick.primitive.getGeometryInstanceAttributes(
              pick.id
            );
            // 判断以前是否选择该要素
            if (attributes != previousPickedClassPrimitive.feature) {
              if (previousPickedClassPrimitive.feature != undefined) {
                // 还原以前选择要素的原本颜色
                previousPickedClassPrimitive.feature.color =
                  previousPickedClassPrimitive.originalColor;
                // 将当前选择要素及其颜色添加到previousPickedClassPrimitive
                previousPickedClassPrimitive.feature = attributes;
                previousPickedClassPrimitive.originalColor = attributes.color;
              }
              // 将当前选择要素及其颜色添加到previousPickedClassPrimitive
              previousPickedClassPrimitive.feature = attributes;
              previousPickedClassPrimitive.originalColor = attributes.color;
            }

            attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
              index % 2 == 0
                ? Cesium.Color.AQUA.withAlpha(0.3)
                : Cesium.Color.AQUA.withAlpha(0.3)
            );
          } else {
            // console.log("没有选中楼层！！！");
            if (previousPickedClassPrimitive.feature != undefined) {
              // 还原以前选择要素的原本颜色
              previousPickedClassPrimitive.feature.color =
                previousPickedClassPrimitive.originalColor;
              // 将previousPickedClassPrimitive的属性设置为undefined
              previousPickedClassPrimitive.feature = undefined;
              previousPickedClassPrimitive.originalColor = undefined;
            }
          }

          // primitive 标绘
          if (
            pick.hasOwnProperty("id") &&
            pick.id instanceof Cesium.Entity &&
            pick.primitive
          ) {
            var entity = pick.id;
            // console.log("选中了某个标绘：", pick);

            // 判断选择是否为Billboard，即图标
            if (pick.primitive instanceof Cesium.Billboard) {
              // console.log("该标绘是Billboard", entity);
              if (!entity.id.includes("billboard")) {
                return;
              }
              let type = entity.id.split("billboard_")[1].split("_")[0];
              let dataId = entity.id.split("billboard_")[1].split("_")[1];
              self.hoverEntities(viewer, "billboard", type, dataId);
              self.hoverEntities(viewer, "label", type, dataId);
              if (type == "community") {
                self.hoverEntities(viewer, "polygon", "community", dataId); // 特殊处理：小区polygon
              }
            } else {
              // console.log("该标绘不是Billboard");
            }

            // 判断选择是否为Primitive，即面、圆柱体、圆锥体等
            if (pick.primitive instanceof Cesium.Primitive) {
              // console.log('该标绘是Primitive', entity)
              if (entity.id.includes("polygon")) {
                let type = entity.id.split("polygon_")[1].split("_")[0];
                let dataId = entity.id.split("polygon_")[1].split("_")[1];
                self.hoverEntities(viewer, "polygon", type, dataId);
                self.hoverEntities(viewer, "label", type, dataId);
                if (type == "community") {
                  self.hoverEntities(viewer, "billboard", "community", dataId); // 特殊处理：小区billboard
                }
              }
            } else {
              // console.log("该标绘不是Primitive");
            }

            // 判断选择是否为Model
            if (pick.primitive instanceof Cesium.Model) {
              // console.log('Model', entity)
              let attributes = entity.model;
              let floor = entity.id.split("model_")[1].split("_")[1]; // 第几层
              let number = entity.id.split("model_")[1].split("_")[0]; // 楼号、楼栋名称
              if (number.includes("-TOP")) {
                self.$refs.floorPopup.openOrCloseFloorPopup(false);
                if (previousPickedModel.feature != undefined) {
                  // 还原以前选择要素的原本颜色
                  previousPickedModel.feature.color =
                    previousPickedModel.originalColor;
                  // 将previousPickedModel的属性设置为undefined
                  previousPickedModel.feature = undefined;
                  previousPickedModel.originalColor = undefined;
                }
                return;
              }

              // 判断以前是否选择该要素
              if (attributes != previousPickedModel.feature) {
                if (previousPickedModel.feature != undefined) {
                  // 还原以前选择要素的原本颜色
                  previousPickedModel.feature.color =
                    previousPickedModel.originalColor;
                  // 将当前选择要素及其颜色添加到previousPickedModel
                  previousPickedModel.feature = attributes;
                  previousPickedModel.originalColor = attributes.color;
                }
                // 将当前选择要素及其颜色添加到previousPickedModel
                previousPickedModel.feature = attributes;
                previousPickedModel.originalColor = attributes.color;
              }
              attributes.color = new Cesium.Color(
                self.activeBuildingColor.r / 255,
                self.activeBuildingColor.g / 255,
                self.activeBuildingColor.b / 255,
                self.activeBuildingColor.a
              );

              // console.log(
              //   entity.position._value,
              //   viewer.scene.globe.pick(
              //     viewer.camera.getPickRay(event.endPosition),
              //     viewer.scene
              //   )
              // );
              self.openFloorPopup(viewer, {
                // gisPosition: entity.position._value,
                // gisPosition:viewer.scene.globe.pick(
                //   viewer.camera.getPickRay(event.endPosition),
                //   viewer.scene
                // ),
                gisPosition:
                  viewer.scene.globe.pick(
                    viewer.camera.getPickRay(event.endPosition),
                    viewer.scene
                  ) == undefined
                    ? entity.position._value
                    : viewer.scene.globe.pick(
                        viewer.camera.getPickRay(event.endPosition),
                        viewer.scene
                      ),
                apiData: entity.id
                  ? {
                      number: number,
                      floor: floor,
                      floorInfos:
                        self.$store.state.oneBuildingFloorListInfos &&
                        self.$store.state.oneBuildingFloorListInfos.length > 0
                          ? self.$store.state.oneBuildingFloorListInfos[
                              floor ? floor - 1 : 0
                            ]
                          : null,
                    }
                  : null, // "model_73栋_6"
              });
            } else {
              // console.log("该标绘不是Model");
              self.$refs.floorPopup.openOrCloseFloorPopup(false);
              if (previousPickedModel.feature != undefined) {
                // 还原以前选择要素的原本颜色
                previousPickedModel.feature.color =
                  previousPickedModel.originalColor;
                // 将previousPickedModel的属性设置为undefined
                previousPickedModel.feature = undefined;
                previousPickedModel.originalColor = undefined;
              }
            }

            // 判断选择是否为Cesium3DTileset
            if (pick.primitive instanceof Cesium.Cesium3DTileset) {
              // console.log('Cesium3DTileset', entity)
            } else {
              // console.log("该标绘不是Cesium3DTileset");
            }
          } else {
            // console.log("没有选中标绘！！！");
            self.hoverEntities(viewer, "billboard", null, null);
            self.hoverEntities(viewer, "polygon", null, null);
            self.hoverEntities(viewer, "label", null, null);
          }
        } else {
          self.$refs.cesiumMapTooltip.openOrCloseTooltip(false);
          self.$refs.floorPopup.openOrCloseFloorPopup(false);
          if (previousPickedEntity.feature != undefined) {
            // 还原以前选择要素的原本颜色
            previousPickedEntity.feature.color =
              previousPickedEntity.originalColor;
            // 将previousPickedEntity_3DTileFeature的各项key设置为undefined
            previousPickedEntity.feature = undefined;
            previousPickedEntity.originalColor = undefined;
          }
          if (previousPickedClassPrimitive.feature != undefined) {
            // 还原以前选择要素的原本颜色
            previousPickedClassPrimitive.feature.color =
              previousPickedClassPrimitive.originalColor;
            // 将previousPickedClassPrimitive的属性设置为undefined
            previousPickedClassPrimitive.feature = undefined;
            previousPickedClassPrimitive.originalColor = undefined;
          }
          if (previousPickedModel.feature != undefined) {
            // 还原以前选择要素的原本颜色
            previousPickedModel.feature.color =
              previousPickedModel.originalColor;
            // 将previousPickedModel的属性设置为undefined
            previousPickedModel.feature = undefined;
            previousPickedModel.originalColor = undefined;
          }
          self.hoverEntities(viewer, "billboard", null, null);
          self.hoverEntities(viewer, "polygon", null, null);
          self.hoverEntities(viewer, "label", null, null);
        }
      }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

      // 点击
      handler.setInputAction(function (event) {
        if (Cesium.defined(pick)) {
          // 判断选择是否为Cesium3DTileFeature，即3D瓦片集（3D楼栋建筑）
          if (pick instanceof Cesium.Cesium3DTileFeature) {
            let buildingInfo = self.returnBuildingInfo(
              viewer,
              pick,
              event.position
            );
            // 根据buildingInfo创建data
            let data = [];
            for (let index = 0; index < buildingInfo.floorTotal; index++) {
              data.push({
                // isShow: true,
                id: index + 1,
                name: buildingInfo.number,
                position: {
                  lng: buildingInfo.position.lng,
                  lat: buildingInfo.position.lat,
                  height:
                    0 +
                    index * buildingInfo.floorHeigth +
                    buildingInfo.floorHeigth / 2,
                },
                positions: buildingInfo.positions,
                properties: {
                  defaultColor:
                    index % 2 == 0
                      ? Cesium.Color.AQUA.withAlpha(0)
                      : Cesium.Color.AQUA.withAlpha(0),
                  hoverColor:
                    index % 2 == 0
                      ? Cesium.Color.AQUA.withAlpha(1)
                      : Cesium.Color.AQUA.withAlpha(1),
                  activeColor: Cesium.Color.AQUA.withAlpha(1),
                  height: 0 + index * buildingInfo.floorHeigth,
                  extrudedHeight: (index + 1) * buildingInfo.floorHeigth,
                  popupConfig: {
                    width: 592,
                    height: 264,
                  },
                  apiData: {
                    name: buildingInfo.number,
                    content: buildingInfo.number,
                  },
                },
                PolygonGeometry: true,
              });
            }
            let type = buildingInfo.number;
            /* // 单击楼栋，分层单体化
            var polygonClassificationPrimitives =
              self.createClassificationPrimitive(viewer, data, type);
            // vue绑定数据
            CesiumGlobeData.vuePolygonClassificationPrimitives =
              polygonClassificationPrimitives; */

            let query = {
              lng: buildingInfo.position.lng,
              lat: buildingInfo.position.lat,
              height: buildingInfo.height,
              number: buildingInfo.number,
              floorTotal: buildingInfo.floorTotal,
              floorHeigth: buildingInfo.floorHeigth,
            };
            self.skipBuildingDetails(query);
          } else {
          }

          // 判断选择是否为ClassificationPrimitive，即楼栋分层、单体化
          if (
            pick.hasOwnProperty("id") &&
            pick.primitive &&
            pick.primitive instanceof Cesium.ClassificationPrimitive
          ) {
            let name = pick.id
              .split("polygonClassificationPrimitive_")[1]
              .split("_")[0];
            let id = pick.id
              .split("polygonClassificationPrimitive_")[1]
              .split("_")[1];
            let index = Number(id) - 1;
            const attributes = pick.primitive.getGeometryInstanceAttributes(
              pick.id
            );
            attributes.color = Cesium.ColorGeometryInstanceAttribute.toValue(
              Cesium.Color.CORAL.withAlpha(1)
            );
          } else {
          }

          // addBillboardCluster  点聚合
          if (
            pick.hasOwnProperty("id") &&
            pick.id instanceof Array &&
            pick.primitive &&
            pick.primitive instanceof Cesium.Billboard &&
            self.isCluster
          ) {
            var entities = pick.id;
            // console.log(entities);
            // 打开弹窗 拉近视野
            if (entities && entities.length > 0) {
              let clusterArray = [];
              entities.forEach((element) => {
                clusterArray.push(element.properties.apiData._value);
              });
              let entity = entities[0];
              if (!entity.id.includes("billboard")) {
                return;
              }
              let type = entity.id.split("billboard_")[1].split("_")[0];
              let id = entity.id.split("billboard_")[1].split("_")[1];
              self.locationBillboard(type, id, true, clusterArray, 0);
            } else {
              viewer.flyTo(entities, {
                duration: 2.0,
              });
            }
            return;
            self.locationBillboard(type, id, true);
          } else {
          }

          // primitive 标绘
          if (
            pick.hasOwnProperty("id") &&
            pick.id instanceof Cesium.Entity &&
            pick.primitive
          ) {
            var entity = pick.id;

            // 判断选择是否为Billboard，即图标
            if (pick.primitive instanceof Cesium.Billboard) {
              // self.setView_area2(viewer);
              if (!entity.id.includes("billboard")) {
                return;
              }
              let type = entity.id.split("billboard_")[1].split("_")[0];
              let id = entity.id.split("billboard_")[1].split("_")[1];
              if (entity.id.includes("billboard_communityTop")) {
                viewer.camera.flyTo({
                  destination: new Cesium.Cartesian3(
                    self.areaIntroView.position.x,
                    self.areaIntroView.position.y,
                    self.areaIntroView.position.z
                  ),
                  orientation: {
                    heading: Cesium.Math.toRadians(self.areaIntroView.heading),
                    pitch: Cesium.Math.toRadians(self.areaIntroView.pitch),
                    roll: self.areaIntroView.roll,
                  },
                  duration: 3,
                  easingFunction: Cesium.EasingFunction.LINEAR_NONE,
                  complete: function () {
                    // self.$bus.$emit("showOrHidePopup", false);
                    // 隐藏左右两侧信息面板
                    self.$store.commit(
                      "common_store_fun",
                      (e) =>
                        (e.leftOrRightBox = {
                          left: false,
                          right: false,
                        })
                    );
                    self.locationBillboard(type, id, false);
                  },
                });
              } else {
                self.locationBillboard(type, id, true);
              }
            } else {
            }

            // 判断选择是否为Label，即文本
            if (pick.primitive instanceof Cesium.Label) {
              // 小区label
              if (entity.id.includes("billboard_communityTop")) {
                // self.setView_area2(viewer);
                let type = entity.id.split("billboard_")[1].split("_")[0];
                let id = entity.id.split("billboard_")[1].split("_")[1];
                viewer.camera.flyTo({
                  destination: new Cesium.Cartesian3(
                    self.areaIntroView.position.x,
                    self.areaIntroView.position.y,
                    self.areaIntroView.position.z
                  ),
                  orientation: {
                    heading: Cesium.Math.toRadians(self.areaIntroView.heading),
                    pitch: Cesium.Math.toRadians(self.areaIntroView.pitch),
                    roll: self.areaIntroView.roll,
                  },
                  duration: 3,
                  easingFunction: Cesium.EasingFunction.LINEAR_NONE,
                  complete: function () {
                    // self.$bus.$emit("showOrHidePopup", false);
                    // 隐藏左右两侧信息面板
                    self.$store.commit(
                      "common_store_fun",
                      (e) =>
                        (e.leftOrRightBox = {
                          left: false,
                          right: false,
                        })
                    );
                    self.locationBillboard(type, id, false);
                  },
                });
              }
            } else {
            }

            // 判断选择是否为Primitive，即面、圆柱体、圆锥体等
            if (pick.primitive instanceof Cesium.Primitive) {
              // console.log(entity.id)
              if (entity.id.includes("communityWall")) {
                self.setView_area2(viewer);
              }
              if (entity.id.includes("polygon")) {
                let type = entity.id.split("polygon_")[1].split("_")[0];
                let id = entity.id.split("polygon_")[1].split("_")[1];
                self.activetEntity(viewer, "polygon", type, id);
                if (type == "community" || type == "grid") {
                  self.activetEntity(viewer, "billboard", "community", id); // 特殊处理：小区/网格billboard
                }

                if (
                  entity.properties.popupConfig._value.height != 0 &&
                  entity.properties.popupConfig._value.width != 0
                ) {
                  self.openPopup(viewer, "polygon", type, id);
                }

                let entity_billboard = self.getEntityById(
                  viewer,
                  "billboard",
                  type,
                  id
                );
                self.viewerFlyTo(
                  viewer,
                  entity_billboard,
                  {
                    duration: self.plotFlyOptions.duration,
                    offset: {
                      heading: Cesium.Math.toRadians(
                        self.plotFlyOptions.offset.heading
                      ), // 方向
                      pitch: Cesium.Math.toRadians(
                        self.plotFlyOptions.offset.pitch
                      ), // 倾斜角度
                      range: self.plotFlyOptions.offset.range,
                    },
                  }
                  // entity_billboard.properties.popupConfig._value.height / 1.6
                  // 90
                );
              }
            } else {
            }

            // 判断选择是否为Model
            if (pick.primitive instanceof Cesium.Model) {
              let obj = {
                number: pick.id.id.split("model_")[1].split("_")[0],
                floor: pick.id.id.split("model_")[1].split("_")[1],
              };
              console.log(pick, pick.mesh.name, obj);
              if (obj.number.includes("-TOP")) {
                return;
              }
              // loadModel
              // pick.id.model.color = new Cesium.Color(
              //   self.activeBuildingColor.r / 255,
              //   self.activeBuildingColor.g / 255,
              //   self.activeBuildingColor.b / 255,
              //   self.activeBuildingColor.a
              // );
              self.$refs.floorPopup
                ? self.$refs.floorPopup.openOrCloseFloorPopup(false)
                : "";
              self.$refs.floorDetails.openOrClose(true);
              self.$refs.floorDetails.setActiveFloor(Number(obj.floor));
              self.$refs.floorDetails.setNumber(obj.number);
            } else {
            }

            // 判断选择是否为Cesium3DTileset
            if (pick.primitive instanceof Cesium.Cesium3DTileset) {
            } else {
            }
          } else {
            self.activetEntity(viewer, "billboard", null, null);
            // self.activetEntity(viewer, "polygon", null, null);
          }
        } else {
          self.activetEntity(viewer, "billboard", null, null);
          // self.activetEntity(viewer, "polygon", null, null);
          self.removeClassificationPrimitives(viewer);
          // self.setView_area(viewer);// 设置为小区视野
          self.removeBillboardSpecialEffects(viewer);
        }
      }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    },
    
    // 返回楼栋信息
    returnBuildingInfo(viewer, pick, pt) {
      let TILESETNAME = decodeURIComponent(
        pick.content.url.split("/static/tileset/")[1].split("/")[0]
      );
      let buildingInfo = {};
      let positions = [];
      if (pick.getProperty("polygon")) {
        pick
          .getProperty("polygon")
          .split(",")
          .forEach((element) => {
            if (element) {
              positions.push(Number(element));
            }
          });
      }
      if (TILESETNAME == "新竹-科技风格") {
        buildingInfo = {
          // pick: pick,
          pick: null,
          id: pick.getProperty("louhao"),
          name: pick.getProperty("louhao"),
          featureId: pick.featureId, // Tile拾取的featureId
          number: pick.getProperty("louhao"), // 楼栋编号
          height: pick.getProperty("Building_h"), // 楼栋总高度
          floorHeigth: pick.getProperty("higth"), // 楼栋各楼层的高度
          floorTotal: pick.getProperty("Floor"), // 楼栋楼层总数量
          position: {
            lng: pick.getProperty("Center")
              ? Number(pick.getProperty("Center").split(",")[0])
              : undefined,
            lat: pick.getProperty("Center")
              ? Number(pick.getProperty("Center").split(",")[1])
              : undefined,
            height: 0,
          }, // 楼栋的中心点
          positions: positions, // 楼栋的polygon
        };
      }
      if (TILESETNAME == "新竹-实景风格") {
        var cartograhphic =
          viewer.scene.globe.ellipsoid.cartesianToCartographic(
            viewer.scene.globe.pick(viewer.camera.getPickRay(pt), viewer.scene)
          );
        if (!cartograhphic) {
          return;
        }
        var lat = Cesium.Math.toDegrees(cartograhphic.latitude);
        var lng = Cesium.Math.toDegrees(cartograhphic.longitude);
        buildingInfo = tilesetKey[pick.getProperty("name")]
          ? tilesetKey[pick.getProperty("name")]
          : {
              // pick: pick,
              pick: null,
              id: pick.getProperty("name"),
              name: pick.getProperty("name"),
              featureId: 0, // Tile拾取的featureId
              number: pick.getProperty("name"), // 楼栋编号
              height: 21, // 楼栋总高度
              floorHeigth: 3, // 楼栋各楼层的高度
              floorTotal: 7, // 楼栋楼层总数量
              position: {
                lng: lng,
                lat: lat,
                height: 0,
              }, // 楼栋的中心点
              positions: positions, // 楼栋的polygon
            };
      }
      return buildingInfo;
    },

    /**
     * 飞往target处
     * downMove 向下移动距离
     */
    viewerFlyTo(viewer, target, options, downMove, leftMove) {
      var timer;
      let self = this;
      viewer.flyTo(
        target,
        options
          ? {
              duration: options.duration ? options.duration : 3,
              offset: options.offset ? options.offset : {},
            }
          : {}
      );
      if (downMove) {
        // timer ? clearTimeout(timer) : "";
        setTimeout(
          function () {
            self.downMoveFun(viewer, downMove);
          },
          options && options.duration
            ? (options.duration + 0.5) * 1000
            : (3 + 0.5) * 1000
        );
      }
      if (leftMove) {
        setTimeout(
          () => {
            viewer.camera.move(
              new Cesium.Cartesian3(-0.75, -0.25, 0),
              leftMove
            );
          },
          options && options.duration
            ? (options.duration + 0.5) * 1000
            : (3 + 0.5) * 1000
        );
      }
    },
    downMoveFun(viewer, downMove) {
      viewer.camera.move(new Cesium.Cartesian3(-0.25, 0.75, 0.0), downMove);
    },

    /**
     * dataSources
     * https://blog.csdn.net/dahongdahong/article/details/108647230
     * https://blog.csdn.net/dragonrxl/article/details/99740357
     * 飞行漫游 （初始化的飞行漫游、重新加载的飞行漫游）
     */
    flyRoaming_init(viewer) {
      var self = this;
      // 显示左右两侧信息面板
      self.$store.commit(
        "common_store_fun",
        (e) =>
          (e.leftOrRightBox = {
            left: false,
            right: false,
          })
      );
      self.returnMarkers();
      viewer.clock.shouldAnimate = true;
      viewer.clock.canAnimate = true;

      // 加载前，删除所有的
      // viewer.dataSources.removeAll();
      // 加载前，删除单个dataSources组
      if (CesiumGlobeData.czmlData) {
        viewer.dataSources.remove(CesiumGlobeData.czmlData);
      }

      /** 1.飞行漫游 */
      var czmlData = Cesium.CzmlDataSource.load(czml);
      CesiumGlobeData.czmlData = czmlData;
      viewer.dataSources.add(czmlData).then(function (ds) {
        console.log(ds, "=====================");
        CesiumGlobeData.flyEntity = ds.entities.getById("path");
        CesiumGlobeData.flyEntity.position.setInterpolationOptions({
          interpolationDegree: 5,
          interpolationAlgorithm: Cesium.LagrangePolynomialApproximation,
        });
        viewer.trackedEntity = CesiumGlobeData.flyEntity;
      });

      // 相机停止移动事件
      // viewer.scene.camera.moveEnd.addEventListener(function(){
      //   console.log('camera.moveEnd',viewer.trackedEntity)
      // });

      /** 2.调整视角 */
      viewer.scene.preRender.addEventListener(self.setRoamView);
    },
    /**
     * 飞行漫游 （暂停后续上的飞行漫游）
     */
    flyRoaming_pause(viewer) {
      var self = this;
      // 显示左右两侧信息面板
      self.$store.commit(
        "common_store_fun",
        (e) =>
          (e.leftOrRightBox = {
            left: false,
            right: false,
          })
      );
      viewer.clock.shouldAnimate = true;
      viewer.clock.canAnimate = true;
      // 添加事件绑定
      viewer.scene.preRender.addEventListener(self.setRoamView);
    },
    /** 停止漫游 */
    stopRoam(viewer) {
      let self = this;
      // 停止动画
      viewer.clock.shouldAnimate = false;
      viewer.clock.canAnimate = false;
      // 删除dataSources czmlData
      viewer.dataSources.removeAll();
      // if (CesiumGlobeData.czmlData) {
      //   viewer.dataSources.remove(CesiumGlobeData.czmlData);
      // }
      // 取消Camera跟踪
      viewer.trackedEntity = undefined;
      // 取消事件绑定
      viewer.scene.preRender.removeEventListener(self.setRoamView);
      // 更改状态
      this.$refs.cesiumMapGridLegend.setIsPlay("stop");
      // 显示左右两侧信息面板
      self.$store.commit(
        "common_store_fun",
        (e) =>
          (e.leftOrRightBox = {
            left: true,
            right: true,
          })
      );
      // 切换到主页视角（小区-前视角）
      self.setView_area(viewer);
    },
    /** 暂停漫游 */
    pauseRoam(viewer) {
      let self = this;
      // 停止动画
      viewer.clock.shouldAnimate = false;
      viewer.clock.canAnimate = false;
      // 取消事件绑定
      viewer.scene.preRender.removeEventListener(self.setRoamView);
      // 更改状态
      this.$refs.cesiumMapGridLegend.setIsPlay("pause");
    },
    setRoamView() {
      var viewer = window.vmCesiumViewer;
      let self = this;
      const target = new Cesium.Cartesian3.fromDegrees(
        108.350314,
        22.81712,
        300
      ); // 让Camera每时每刻对准某一点

      if (CesiumGlobeData.flyEntity) {
        const center = CesiumGlobeData.flyEntity.position.getValue(
          viewer.clock.currentTime
        );

        // 世界坐标转换为经纬度
        var ellipsoid = viewer.scene.globe.ellipsoid;
        var cartesian3 = center;
        var cartograhpinc = cartesian3
          ? ellipsoid.cartesianToCartographic(cartesian3)
          : undefined;
        var lat = cartograhpinc
          ? Cesium.Math.toDegrees(cartograhpinc.latitude)
          : undefined;
        var lng = cartograhpinc
          ? Cesium.Math.toDegrees(cartograhpinc.longitude)
          : undefined;
        console.log(center, lat, lng);
        if (center) {
          CesiumGlobeData.markers.push({
            lng: lng,
            lat: lat,
          });
        } else {
          // 跑完了  3s后，停止漫游
          setTimeout(() => {
            self.stopRoam(viewer);
          }, 3 * 1000);
        }

        if (!(CesiumGlobeData.markers && CesiumGlobeData.markers.length >= 2)) {
          return;
        }
        // 计算两点之间的方向
        const heading = Cesium.Math.toRadians(
          bearing(
            CesiumGlobeData.markers[CesiumGlobeData.markers.length - 2].lat,
            CesiumGlobeData.markers[CesiumGlobeData.markers.length - 2].lng,
            CesiumGlobeData.markers[CesiumGlobeData.markers.length - 1].lat,
            CesiumGlobeData.markers[CesiumGlobeData.markers.length - 1].lng
          )
        );
        // 相机看点的角度，如果大于0那么则是从地底往上看，所以要为负值
        const pitch = Cesium.Math.toRadians(-20.0);
        const range = 200.0;
        if (center) {
          // 1. 围绕一个点：target 漫游，上帝视角
          // const vector = new Cesium.Cartesian3(
          //   target.x - center.x,
          //   target.y - center.y,
          //   300
          // );
          // viewer.camera.lookAt(center, vector);

          // 2. 通过该表heading进行漫游，第一视角
          viewer.camera.lookAt(
            center,
            new Cesium.HeadingPitchRange(heading, pitch, range)
          );
        }
      }
    },
    // 根据czml返回markers的第一个点位\初始化markers
    returnMarkers() {
      let self = this;
      var cartographicDegrees = czml[1].position.cartographicDegrees;
      // 将数据分成4个一组
      var newArr = [];
      var chunk = 4;
      for (var i = 0, j = cartographicDegrees.length; i < j; i += chunk) {
        newArr.push(cartographicDegrees.slice(i, i + chunk));
      }
      if (newArr && newArr.length > 0) {
        CesiumGlobeData.markers = [{ lng: newArr[0][1], lat: newArr[0][2] }];
      }
    },

    /**
     * 特效
     */
    specialEffectsFunction(viewer) {
      let self = this;

      var specialEffects01 = self.createCircleRotate(
        viewer,
        {
          id: 1,
          name: "旋转圆",
          position: { lng: 108.349775, lat: 22.817071, height: 0 },
          material: new Cesium.ImageMaterialProperty({
            image: require("../../assets/images/map/circular_03.png"),
            repeat: Cesium.Cartesian2(1.0, 1.0),
            // color: Cesium.Color.TOMATO.withAlpha(0.2),
            transparent: true,
          }),
        },
        "specialEffects"
      ); // "ellipse_specialEffects_1"
      var specialEffects02 = self.createDynamicRange(viewer); // "ellipse_specialEffects_2"

      /* // 使用纹理绘制线/面
      let item = viewer.entities.add({
        name: "PolylineTrail",
        polyline: {
          positions: Cesium.Cartesian3.fromDegreesArrayHeights([
            108.348264, 22.815942, 10, 
            108.350396, 22.815881, 10,
            108.348264, 22.815476, 10, 
            108.350396, 22.815373, 10,
          ]),
          width: 8,
          material: new Cesium.ImageMaterialProperty({
            image: "static\cesium\trailLink.png",// require
            repeat: Cesium.Cartesian2(1.0, 1.0),
            // color: Cesium.Color.TOMATO.withAlpha(0.2),
            transparent: true,
          }),
          // material: new Cesium.PolylineTrailLinkMaterialProperty(Cesium.Color.fromCssColorString("#0BFF0D"), 10000),
          clampToGround: true
        },
        // polygon: {
        //   hierarchy: Cesium.Cartesian3.fromDegreesArrayHeights([
        //     108.348264, 22.815942, 10, 
        //     108.350396, 22.815881, 10,
        //     108.348264, 22.815476, 10, 
        //     108.350396, 22.815373, 10,
        //   ]),
        //   width: 15,
        //   material: new Cesium.PolylineTrailLinkMaterialProperty(
        //     Cesium.Color.WHITE,
        //     // Cesium.Color.fromCssColorString("#0BFF0D"),
        //     3000,
        //     1
        //   ),
        // },
      }); */
    },
    // 立体墙效果
    drawWall(viewer, positions, data, type) {
      var alp = 1;
      var num = 0;
      // 绘制墙体
      var wall = viewer.entities.add({
        id: "communityWall_" + type + "_" + data.id, // 唯一性

        // name: "流动墙" + "_" + data.id,
        // wall: {
        //   positions: Cesium.Cartesian3.fromDegreesArray(positions),
        //   // 设置高度
        //   maximumHeights: new Array(positions.length).fill(20),
        //   minimunHeights: new Array(positions.length).fill(0),
        //   material: new Cesium.TrailLineMaterialProperty({
        //     viewer: viewer,
        //     color: Cesium.Color.RED.withAlpha(0.7),
        //     duration: 18000,
        //   }),
        // },

        name: "小区围墙" + "_" + data.id,
        wall: {
          positions: Cesium.Cartesian3.fromDegreesArray(positions),
          // maximumHeights: new Array(positions.length).fill(36),
          // minimunHeights: new Array(positions.length).fill(21),
          maximumHeights: new Array(positions.length).fill(36 / 2),
          minimunHeights: new Array(positions.length).fill(21 / 2),
          /** 静态material */
          // material: new Cesium.ImageMaterialProperty({
          //   transparent: true,//设置透明
          //   image: require("../../assets/images/map/RArrow.png"),// require
          //   repeat: new Cesium.Cartesian2(1.0, 1),
          // }),
          /** 动态material */
          material: new Cesium.DynamicWallMaterialPropertyTwo({
            viewer: viewer,
            // trailImage: "./static/cesium/dzwl.png", // require
            // trailImage: require("../../assets/images/map/RArrow.png"),
            trailImage: require("../../assets/images/map/dzwl.png"),
            color: Cesium.Color.BLUE,
            duration: 3000 * 1000,
          }),
        },

        // name: "动态立体墙" + "_" + data.id,
        // wall: {
        //   positions: Cesium.Cartesian3.fromDegreesArray(positions),
        //   // 设置高度
        //   maximumHeights: new Array(positions.length).fill(10),
        //   minimunHeights: new Array(positions.length).fill(0),
        //   material: new Cesium.DynamicWallMaterialProperty({
        //     viewer: viewer,
        //     color: Cesium.Color.fromBytes(55, 96, 56).withAlpha(0.7),
        //     duration: 3000,
        //   }),
        // },

        // name: "动态立体墙-颜色渐变,呼吸灯效果" + "_" + data.id,
        // wall: {
        //   show: true,
        //   positions: Cesium.Cartesian3.fromDegreesArray(positions),
        //   material: new Cesium.ImageMaterialProperty({
        //     image: "/static/cesium/colors.png",// require
        //     transparent: true,
        //     color: new Cesium.CallbackProperty(function () {
        //       if (num % 2 === 0) {
        //         alp -= 0.005;
        //       } else {
        //         alp += 0.005;
        //       }

        //       if (alp <= 0.3) {
        //         num++;
        //       } else if (alp >= 1) {
        //         num++;
        //       }
        //       return Cesium.Color.WHITE.withAlpha(alp);
        //       //entity的颜色透明 并不影响材质，并且 entity也会透明
        //     }, false),
        //   }),
        // },
      });

      return wall;
    },
    // 正多边形扩散
    createWallRegularDiffuse(viewer, lng, lat, id, color) {
      let self = this;
      // 清除原来的
      if (CesiumGlobeData.specialEffectsWallRegularDiffuse) {
        viewer.entities.remove(
          CesiumGlobeData.specialEffectsWallRegularDiffuse
        );
      }
      WallRegularDiffuse({
        viewer: viewer,
        center: [lng, lat],
        radius: 10.0,
        edge: 20,
        height: 10.0,
        speed: 20,
        minRadius: 0.0,
        color: color || new Cesium.Color(1.0, 0.0, 0.0, 1.0),
        id: id,
        type: "specialEffects",
      });
      let entity = self.getEntityById(viewer, "wall", "specialEffects", id);
      CesiumGlobeData.specialEffectsWallRegularDiffuse = entity;
      return entity;
    },
    // 雷达扫描
    createRadarScan(viewer, data, type) {
      let self = this;
      // 清除原来的
      if (CesiumGlobeData.specialEffectsRadarScan) {
        viewer.entities.remove(CesiumGlobeData.specialEffectsRadarScan);
      }

      // radarSolidScan({
      //     viewer: viewer,
      //     position: [108.349775, 22.817071],
      //     radius: 300.0,
      //     color: new Cesium.Color(1.0, 1.0, 0.0, 0.3),
      //     speed: 5.0,
      //     id: 1,
      //     type:'specialEffects',
      // })
      // return self.getEntityById(viewer, "ellipsoid", "specialEffects", 1);

      let num = 0;
      const randar = viewer.entities.add({
        id: "ellipsoid_" + type + "_" + data.id, // 唯一性
        name: data.name + "_" + data.id,
        position: Cesium.Cartesian3.fromDegrees(
          data.position.lng,
          data.position.lat,
          data.position.height
        ),
        orientation: new Cesium.CallbackProperty(() => {
          num += 1;
          if (num >= data.maxAngle) num = 0;
          return Cesium.Transforms.headingPitchRollQuaternion(
            Cesium.Cartesian3.fromDegrees(
              data.position.lng,
              data.position.lat,
              data.position.height
            ),
            new Cesium.HeadingPitchRoll((num * Math.PI) / 180, 0, 0)
          );
        }, false),
        ellipsoid: {
          radii: data.radii || new Cesium.Cartesian3(5000.0, 5000.0, 2000.0), // 扇形半径
          innerRadii: data.innerRadii || new Cesium.Cartesian3(1.0, 1.0, 1.0), // 内半径
          minimumClock: Cesium.Math.toRadians(-20),
          maximumClock: Cesium.Math.toRadians(20),
          minimumCone: Cesium.Math.toRadians(90), // 上下偏角  可以都设置为90
          maximumCone: Cesium.Math.toRadians(90),
          material: Cesium.Color.AQUA.withAlpha(0.5),
          outline: true,
          outlineColor: Cesium.Color.AQUA.withAlpha(0.8),
          heightReference: Cesium.HeightReference.RELATIVE_TO_GROUND, //RELATIVE_TO_GROUND CLAMP_TO_GROUND
        },
      });
      CesiumGlobeData.specialEffectsRadarScan = randar;
      return randar;
    },
    // 动态扩散圆
    createDynamicRange(viewer) {
      let self = this;

      let entity = new DynamicRange({
        viewer: viewer,
        type: "specialEffects",
        id: 2,
        lng: 108.349775,
        lat: 22.817071,
      });
      entity.dynamicRange({
        minR: 64, // 最小半径
        maxR: 300, // 最大半径
        deviationR: 1, // 每次增加的大小
      });
      return self.getEntityById(viewer, "ellipse", "specialEffects", 2);
    },
    // 旋转圆
    createCircleRotate(viewer, data, type) {
      let self = this;
      let entity = viewer.entities.add({
        id: "ellipse_" + type + "_" + data.id, // 唯一性
        name: data.name + "-" + data.id,
        position: Cesium.Cartesian3.fromDegrees(
          data.position.lng,
          data.position.lat,
          data.position.height
        ),
        ellipse: {
          semiMinorAxis: 64.0,
          semiMajorAxis: 64.0,
          material: data.material,
        },
      });
      rotateMaterial(entity.ellipse, 0, 1); // 旋转圆 stRotation
      return entity;
    },
    // 清除Billboard上的激活特效
    removeBillboardSpecialEffects(viewer) {
      if (CesiumGlobeData.specialEffectsRadarScan) {
        viewer.entities.remove(CesiumGlobeData.specialEffectsRadarScan);
      }
      if (CesiumGlobeData.specialEffectsWallRegularDiffuse) {
        viewer.entities.remove(
          CesiumGlobeData.specialEffectsWallRegularDiffuse
        );
      }
    },

    /**
     * 标绘（画点、线、面、文字、图标等，加载gltf模型）
     * https://cesium.com/learn/cesiumjs/ref-doc/PinBuilder.html
     * https://cesium.com/docs/cesiumjs-ref-doc/PointGraphics.html
     * https://cesium.com/docs/cesiumjs-ref-doc/PolylineGraphics.html
     * https://cesium.com/docs/cesiumjs-ref-doc/PolygonGraphics.html
     * https://cesium.com/docs/cesiumjs-ref-doc/LabelGraphics.html
     * https://cesium.com/docs/cesiumjs-ref-doc/BillboardGraphics.html
     * https://cesium.com/docs/cesiumjs-ref-doc/ModelGraphics.html
     * https://cesium.com/learn/cesiumjs/ref-doc/Entity.html
     * https://cesium.com/learn/cesiumjs/ref-doc/EntityCollection.html
     * https://blog.csdn.net/qq_17627195/article/details/109237689
     * pin、point、billboard、polyline、polygon、model，Entity
     */
    entityFunction(viewer) {
      let self = this;
      /** 先清空所有 */
      viewer.entities.removeAll();

      var communityWall;
      self
        .axios({
          url: `${self.$common.basePathA}/backStage/housingEstate/selectInformation`,
          method: "get",
          params: {},
          hideLoading: true,
        })
        .then(function (res) {
          // console.log(res.data);
          // housingEstate 小区相关数据
          if (res.data) {
            const ele = res.data;
            ele.gdjj = "";
            if (ele.trafficPolice) {
              ele.trafficPolice.forEach((element) => {
                ele.gdjj += element.xm + " ";
              });
            }

            self.poiIconLabelAdd(viewer, ele);

            /** 小区的围墙 */
            const positions = ele.fw
              ? ele.fw.includes("POLYGON((") && ele.fw.includes("))")
                ? ele.fw
                    .split("POLYGON((")[1]
                    .split("))")[0]
                    .replaceAll(" ", ",")
                    .split(",")
                : []
              : [];
            const newpositions = [];
            positions.forEach((position) => {
              newpositions.push(Number(position));
            });
            communityWall = self.drawWall(
              viewer,
              newpositions,
              {
                id: ele.id,
              },
              "communityWall"
            );
            // 显隐
            if (communityWall) {
              self.isShowEntities(
                viewer.entities.values,
                self.plotStatus.communityWall,
                "communityWall",
                "communityWall"
              );
            }

            // vue绑定数据
            if (!CesiumGlobeData.vuePlot) {
              CesiumGlobeData.vuePlot = new Object();
            }
            if (!CesiumGlobeData.vuePlot.wall) {
              CesiumGlobeData.vuePlot.wall = new Object();
            }
            CesiumGlobeData.vuePlot.wall.communityWall = communityWall; // 小区的围墙
          } else {
            console.log("未获取到小区相关数据！");
          }
        })
        .catch(function (error) {
          console.error(error);
          // self.$message.error(error);
        });

      /** 网格、小区 */
      let gridPolygons = []; // polygon数据
      let gridArray = []; // billboard、label数据
      var entities_label_grid, entities_billboard_grid, entitiesPolygon;
      // for (const key in grid) {
      //   if (Object.hasOwnProperty.call(grid, key)) {
      //     const ele = grid[key];
      //   }
      // }
      self
        .axios({
          url: `${self.$common.basePathA}/backStage/gird/getAll`,
          method: "get",
          params: {},
          hideLoading: true,
        })
        .then(function (res) {
          // console.log(res.data);
          const zw = [
            {
              label: "社工",
              value: 1,
            },
            {
              label: "党建指导员",
              value: 2,
            },
            {
              label: "区党委保卫办主任",
              value: 3,
            },
            {
              label: "总务处主任",
              value: 4,
            },
            {
              label: "协管员",
              value: 5,
            },
            {
              label: "团支部书记",
              value: 6,
            },
            {
              label: "妇联主席",
              value: 7,
            },
            {
              label: "后勤主任",
              value: 8,
            },
            {
              label: "其他",
              value: 9,
            },
          ];
          const conf = [
            {
              material: Cesium.Color.AQUA.withAlpha(0.2),
              outlineColor: Cesium.Color.AQUA,
            },
            {
              material: Cesium.Color.TOMATO.withAlpha(0.2),
              outlineColor: Cesium.Color.TOMATO,
            },
            {
              material: Cesium.Color.FUCHSIA.withAlpha(0.2),
              outlineColor: Cesium.Color.FUCHSIA,
            },
            {
              material: Cesium.Color.LAWNGREEN.withAlpha(0.2),
              outlineColor: Cesium.Color.LAWNGREEN,
            },
            {
              material: Cesium.Color.SANDYBROWN.withAlpha(0.2),
              outlineColor: Cesium.Color.SANDYBROWN,
            },
            {
              material: Cesium.Color.WHITE.withAlpha(0.2),
              outlineColor: Cesium.Color.WHITE,
            },
          ];
          function valueConversionLabel(array, value) {
            let result = "";
            array.forEach((element) => {
              if (element.value == value) {
                result = element.label;
                return;
              }
            });
            return result;
          }

          let ids = [];
          self.plotStatus.grid && self.plotStatus.grid.length > 0
            ? res.data.forEach((item) => {
                ids.push(item.id);
              })
            : "";
          self.plotStatus.grid = ids;

          res.data.forEach((ele, index) => {
            ele.index = index + 1 + "";
            ele.mc = ele.wgmc;
            ele.wgqy = ele.qy;
            ele.syrk = ele.population; // 实有人口
            ele.sssq = "新竹社区";
            ele.lds = ele.building; // 楼栋数
            ele.hs = ele.house; // 户数
            ele.czrk = ele.permanent; // 常住人口
            ele.ldrk = ele.migrant; // 流动人口
            ele.dyrs = ele.partyMember; // 党员数量
            ele.nmsc = ele.market; // 农贸市场
            ele.xx = ele.school; // 学校
            ele.wgy = [];
            ele.wgz = [];
            ele.worker.forEach((element) => {
              element.lx == 1
                ? ele.wgy.push({
                    zwmc: valueConversionLabel(zw, element.zw),
                    ...element,
                  })
                : "";
              element.lx == 10 ? ele.wgz.push(element) : "";
            });
            const positions = ele.fw
              ? ele.fw.includes("POLYGON((") && ele.fw.includes("))")
                ? ele.fw
                    .split("POLYGON((")[1]
                    .split("))")[0]
                    .replaceAll(" ", ",")
                    .split(",")
                : []
              : [];
            const newpositions = [];
            positions.forEach((position) => {
              newpositions.push(Number(position));
            });
            // polygon
            gridPolygons.push({
              isShow:
                self.plotStatus.grid && self.plotStatus.grid.length > 0
                  ? self.plotStatus.grid.indexOf(ele.id) != -1
                  : false, // 是否显示
              id: ele.id,
              name: ele.wgmc,
              position: {
                lng: ele.jd,
                lat: ele.wd,
                height: 0,
              },
              positions: newpositions,
              properties: {
                defaultColor: {
                  material: conf[index > 4 ? 5 : index].material,
                  outlineColor: conf[index > 4 ? 5 : index].outlineColor,
                },
                activeColor: {
                  material: Cesium.Color.RED.withAlpha(0.2),
                  outlineColor: Cesium.Color.RED,
                },
                popupConfig: {
                  width: 750,
                  height: 368,
                },
                apiData: {
                  name: ele.wgmc,
                  content: "网格介绍",
                },
              },
              polygon: true,
            });
            // billboard、label
            gridArray.push({
              isShow:
                self.plotStatus.grid && self.plotStatus.grid.length > 0
                  ? self.plotStatus.grid.indexOf(ele.id) != -1
                  : false, // 是否显示
              id: ele.id,
              name: ele.wgmc,
              position: { lng: ele.jd, lat: ele.wd, height: 0 },
              properties: {
                defaultImage: {
                  name: "grid/grid-" + (index + 1 < 6 ? index + 1 : 7) + ".png",
                  height: 100,
                  width: 88,
                },
                activeImage: {
                  name: "grid/grid-" + (index + 1 < 6 ? index + 1 : 7) + ".png",
                  height: 100,
                  width: 88,
                },
                billboardColor: Cesium.Color.WHITE,
                billboardFalseHoverColor: Cesium.Color.WHITE.withAlpha(0.5),
                labelFillColor: Cesium.Color.ROYALBLUE,
                popupConfig: {
                  width: 750,
                  height: 368,
                },
                apiData: ele,
              },
              billboard: true,
              label: true,
            });
            // console.log(ele)
          });
          entities_label_grid = self.addLabel(viewer, gridArray, "grid");
          entities_billboard_grid = self.addBillboard(
            viewer,
            gridArray,
            "grid"
          );
          entitiesPolygon = self.addPolygon(viewer, gridPolygons, "grid");

          // vue绑定数据
          if (!CesiumGlobeData.vuePlot) {
            CesiumGlobeData.vuePlot = new Object();
          }
          if (!CesiumGlobeData.vuePlot.label) {
            CesiumGlobeData.vuePlot.label = new Object();
          }
          CesiumGlobeData.vuePlot.label.grid = entities_label_grid; // 网格
          // CesiumGlobeData.vuePlot.label.community = entities3_ // 小区
          if (!CesiumGlobeData.vuePlot.billboard) {
            CesiumGlobeData.vuePlot.billboard = new Object();
          }
          CesiumGlobeData.vuePlot.billboard.grid = entities_billboard_grid; // 网格
          // CesiumGlobeData.vuePlot.billboard.community = entities3 // 小区
          if (!CesiumGlobeData.vuePlot.polygon) {
            CesiumGlobeData.vuePlot.polygon = new Object();
          }
          CesiumGlobeData.vuePlot.polygon.grid = entitiesPolygon; // 网格
          // CesiumGlobeData.vuePlot.polygon.community = entities30 // 小区
        })
        .catch(function (error) {
          console.error(error);
          // self.$message.error(error);
        });

      // 绘标
      self
        .axios({
          url: `${self.$common.basePathA}/map/getMapBase`,
          method: "get",
          params: {},
          hideLoading: true,
        })
        .then(function (res) {
          console.log(res);
          // 化粪池
          let entities_label_septicTank = null;
          let entities_billboard_septicTank = null;
          // 监控设备
          let entities_label_monitoring = null;
          let entities_billboard_monitoring = null;
          // 防疫设备
          let entities_label_antiepidemic = null;
          let entities_billboard_antiepidemic = null;
          // 闸机
          let entities_label_gate = null;
          let entities_billboard_gate = null;
          // 消防
          let entities_label_fireHydrant = null;
          let entities_billboard_fireHydrant = null;
          // 入口
          let entities_label_entrance = null;
          let entities_billboard_entrance = null;
          let entities_title_entrance = null;
          if (res.code == 200) {
            let data = res.data;
            if (data) {
              // septicTankRobotList 化粪池
              if (
                data.septicTankRobotList &&
                data.septicTankRobotList.length > 0
              ) {
                let septicTankArray = [];
                data.septicTankRobotList.forEach((element) => {
                  if (element.jd && element.wd) {
                    septicTankArray.push({
                      isShow: self.plotStatus.septicTank,
                      id: element.id,
                      name: element.mc,
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "septicTank/map-normal.png",
                          height: 56,
                          width: 40,
                        },
                        activeImage: {
                          name: "septicTank/map-select.png",
                          height: 68,
                          width: 48,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.TOMATO,
                        popupConfig: {
                          width: 542,
                          height: 284,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });

                if (septicTankArray && septicTankArray.length > 0) {
                  console.log("map-化粪池数据", septicTankArray);
                  entities_label_septicTank = self.addLabel(
                    viewer,
                    septicTankArray,
                    "septicTank"
                  );
                  if (self.isCluster) {
                    entities_billboard_septicTank = self.addBillboardCluster(
                      viewer,
                      septicTankArray,
                      "septicTank"
                    );
                  } else {
                    entities_billboard_septicTank = self.addBillboard(
                      viewer,
                      septicTankArray,
                      "septicTank"
                    );
                  }
                } else {
                  entities_label_septicTank = null;
                  entities_billboard_septicTank = null;
                  console.log("未获取到化粪池数据！");
                }
              } else {
                entities_label_septicTank = null;
                entities_billboard_septicTank = null;
                console.log("未获取到化粪池数据！");
              }

              // cameraList 监控设备
              if (data.cameraList && data.cameraList.length > 0) {
                let monitoringArray = [];
                data.cameraList.forEach((element) => {
                  if (element.jd && element.wd) {
                    monitoringArray.push({
                      isShow: self.plotStatus.monitoring,
                      id: element.id,
                      name: element.mc,
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "monitoring/map-normal.png",
                          height: 56,
                          width: 40,
                        },
                        activeImage: {
                          name: "monitoring/map-select.png",
                          height: 68,
                          width: 48,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.TURQUOISE,
                        popupConfig: {
                          width: 750,
                          height: 388,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });
                if (monitoringArray && monitoringArray.length > 0) {
                  console.log("map-监控设备数据", monitoringArray);
                  entities_label_monitoring = self.addLabel(
                    viewer,
                    monitoringArray,
                    "monitoring"
                  );
                  if (self.isCluster) {
                    entities_billboard_monitoring = self.addBillboardCluster(
                      viewer,
                      monitoringArray,
                      "monitoring"
                    );
                  } else {
                    entities_billboard_monitoring = self.addBillboard(
                      viewer,
                      monitoringArray,
                      "monitoring"
                    );
                  }
                } else {
                  entities_label_monitoring = null;
                  entities_billboard_monitoring = null;
                  console.log("未获取到监控设备数据！");
                }
              } else {
                entities_label_monitoring = null;
                entities_billboard_monitoring = null;
                console.log("未获取到监控设备数据！");
              }

              // antiepidemicList 防疫设备
              if (data.antiepidemicList && data.antiepidemicList.length > 0) {
                let antiepidemicArray = [];
                data.antiepidemicList.forEach((element) => {
                  if (element.jd && element.wd) {
                    antiepidemicArray.push({
                      isShow: self.plotStatus.antiepidemic,
                      id: element.id,
                      name: element.wz,
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "antiepidemic/map-normal.png",
                          height: 56,
                          width: 40,
                        },
                        activeImage: {
                          name: "antiepidemic/map-select.png",
                          height: 68,
                          width: 48,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.FUCHSIA,
                        popupConfig: {
                          width: 520,
                          height: 320,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });
                if (antiepidemicArray && antiepidemicArray.length > 0) {
                  console.log("map-防疫设备数据", antiepidemicArray);
                  entities_label_antiepidemic = self.addLabel(
                    viewer,
                    antiepidemicArray,
                    "antiepidemic"
                  );
                  entities_billboard_antiepidemic = self.addBillboard(
                    viewer,
                    antiepidemicArray,
                    "antiepidemic"
                  );
                } else {
                  entities_label_antiepidemic = null;
                  entities_billboard_antiepidemic = null;
                  console.log("未获取到防疫设备数据！");
                }
              } else {
                entities_label_antiepidemic = null;
                entities_billboard_antiepidemic = null;
                console.log("未获取到防疫设备数据！");
              }

              // gateList 闸机
              if (data.gateList && data.gateList.length > 0) {
                let gateArray = [];
                data.gateList.forEach((element) => {
                  if (element.jd && element.wd) {
                    gateArray.push({
                      isShow: self.plotStatus.gate,
                      id: element.id,
                      name:
                        element.wz +
                        (element.lx
                          ? "（" +
                            ["", "单翼人闸", "双翼人闸", "车辆闸机"][
                              element.lx
                            ] +
                            "）"
                          : ""),
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "gate/map-normal.png",
                          height: 56,
                          width: 40,
                        },
                        activeImage: {
                          name: "gate/map-select.png",
                          height: 68,
                          width: 48,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.YELLOW,
                        popupConfig: {
                          width: 750,
                          height: 358,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });
                if (gateArray && gateArray.length > 0) {
                  console.log("map-闸机数据", gateArray);
                  entities_label_gate = self.addLabel(
                    viewer,
                    gateArray,
                    "gate"
                  );
                  entities_billboard_gate = self.addBillboard(
                    viewer,
                    gateArray,
                    "gate"
                  );
                } else {
                  entities_label_gate = null;
                  entities_billboard_gate = null;
                  console.log("未获取到闸机数据！");
                }
              } else {
                entities_label_gate = null;
                entities_billboard_gate = null;
                console.log("未获取到闸机数据！");
              }

              // housingEstateDoors 入口
              if (
                data.housingEstateDoors &&
                data.housingEstateDoors.length > 0
              ) {
                let entranceArray = [];
                data.housingEstateDoors.forEach((element) => {
                  if (element.jd && element.wd) {
                    entranceArray.push({
                      isShow: self.plotStatus.entrance,
                      id: element.id,
                      name:
                        element.mc +
                        (element.lx
                          ? element.lx == "1"
                            ? "（人员出入口）"
                            : element.lx == "2"
                            ? "（人员出入口、车辆入口）"
                            : element.lx == "3"
                            ? "（人员出入口、车辆出口）"
                            : ""
                          : ""),
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "entrance/map-normal.png",
                          height: 100,
                          width: 80,
                        },
                        activeImage: {
                          name: "entrance/map-select.png",
                          height: 100,
                          width: 80,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.CHARTREUSE,
                        popupConfig: {
                          width: 492,
                          height: 420,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });
                if (entranceArray && entranceArray.length > 0) {
                  console.log("map-入口数据", entranceArray);
                  entities_label_entrance = self.addLabel(
                    viewer,
                    entranceArray,
                    "entrance"
                  );
                  entities_billboard_entrance = self.addBillboard(
                    viewer,
                    entranceArray,
                    "entrance"
                  );
                  entities_title_entrance = self.addTitle(
                    viewer,
                    entranceArray,
                    "entrance"
                  );
                } else {
                  entities_label_entrance = null;
                  entities_billboard_entrance = null;
                  entities_title_entrance = null;
                  console.log("未获取到入口数据！");
                }
              } else {
                entities_label_entrance = null;
                entities_billboard_entrance = null;
                entities_title_entrance = null;
                console.log("未获取到入口数据！");
              }

              // fireHydrantList 消防
              if (data.fireHydrantList && data.fireHydrantList.length > 0) {
                let fireHydrantArray = [];
                data.fireHydrantList.forEach((element) => {
                  if (element.jd && element.wd) {
                    fireHydrantArray.push({
                      isShow: self.plotStatus.fireHydrant,
                      id: element.id,
                      name: element.mc,
                      position: { lng: element.jd, lat: element.wd, height: 0 },
                      properties: {
                        defaultImage: {
                          name: "fireHydrant/map-normal.png",
                          height: 56,
                          width: 40,
                        },
                        activeImage: {
                          name: "fireHydrant/map-select.png",
                          height: 68,
                          width: 48,
                        },
                        billboardColor: Cesium.Color.WHITE,
                        billboardFalseHoverColor:
                          Cesium.Color.WHITE.withAlpha(0.5),
                        labelFillColor: Cesium.Color.RED,
                        popupConfig: {
                          width: 460,
                          height: 300,
                        },
                        apiData: element,
                      },
                      billboard: true,
                      label: true,
                    });
                  }
                });
                if (fireHydrantArray && fireHydrantArray.length > 0) {
                  console.log("map-消防数据", fireHydrantArray);
                  entities_label_fireHydrant = self.addLabel(
                    viewer,
                    fireHydrantArray,
                    "fireHydrant"
                  );
                  entities_billboard_fireHydrant = self.addBillboard(
                    viewer,
                    fireHydrantArray,
                    "fireHydrant"
                  );
                } else {
                  entities_label_fireHydrant = null;
                  entities_billboard_fireHydrant = null;
                  console.log("未获取到消防数据！");
                }
              } else {
                entities_label_fireHydrant = null;
                entities_billboard_fireHydrant = null;
                console.log("未获取到消防数据！");
              }
            } else {
              entities_label_septicTank = null;
              entities_billboard_septicTank = null;
              entities_label_monitoring = null;
              entities_billboard_monitoring = null;
              entities_label_antiepidemic = null;
              entities_billboard_antiepidemic = null;
              entities_label_gate = null;
              entities_billboard_gate = null;
              entities_label_fireHydrant = null;
              entities_billboard_fireHydrant = null;
              entities_label_entrance = null;
              entities_billboard_entrance = null;
              entities_title_entrance = null;
              self.$message.info("未获取地图数据！");
            }
          } else {
            self.$message.info("获取地图数据失败！");
          }

          // vue绑定数据
          CesiumGlobeData.vuePlot = {
            label: {
              septicTank: entities_label_septicTank, // 化粪池
              monitoring: entities_label_monitoring, // 监控设备
              antiepidemic: entities_label_antiepidemic, // 防疫设备
              gate: entities_label_gate, // 闸机
              entrance: entities_label_entrance, // 入口
              fireHydrant: entities_label_fireHydrant, // 消防
              // community: entities3_, // 小区
              grid: entities_label_grid, // 网格
            },
            title: {
              // septicTank: entities_label_septicTank, // 化粪池
              // monitoring: entities_label_monitoring, // 监控设备
              // antiepidemic: entities_label_antiepidemic, // 防疫设备
              // gate: entities_label_gate, // 闸机
              entrance: entities_title_entrance, // 入口
              // fireHydrant: entities_label_fireHydrant, // 消防
              // community: entities3_, // 小区
              // grid: entities_label_grid, // 网格
            },
            billboard: {
              septicTank: entities_billboard_septicTank, // 化粪池
              monitoring: entities_billboard_monitoring, // 监控设备
              antiepidemic: entities_billboard_antiepidemic, // 防疫设备
              gate: entities_billboard_gate, // 闸机
              entrance: entities_billboard_entrance, // 入口
              fireHydrant: entities_billboard_fireHydrant, // 消防
              // community: entities3, // 小区
              grid: entities_billboard_grid, // 网格
            },
            wall: {
              communityWall: communityWall, // 小区的围墙
            },
            polygon: {
              // community: entities30, // 小区
              grid: entitiesPolygon, // 网格
            },
          };
        })
        .catch(function (error) {
          console.error(error);
          // self.$message.error(error);
        });

      // 楼栋mc
      self
        .axios({
          url: `${self.$common.basePathA}/buildingManagement/buildingInformation`,
          method: "post",
          data: {
            needPage: false,
          },
          hideLoading: true,
        })
        .then(function (res) {
          console.log("楼栋mc", res);
          let entities_title_building = null;
          if (res.code == 200) {
            let data = res.data;
            if (data && data.length > 0) {
              let buildingArray = [];
              data.forEach((element, index) => {
                if (element.jd && element.wd) {
                  buildingArray.push({
                    isShow: true,
                    id: element.mc + "-" + index,
                    name: element.zsmc,
                    position: {
                      lng: element.jd,
                      lat: element.wd,
                      height: Number(element.lg),
                    },
                    properties: {
                      defaultImage: {
                        name: "entrance/map-normal.png",
                        height: 100,
                        width: 80,
                      },
                      activeImage: {
                        name: "entrance/map-select.png",
                        height: 100,
                        width: 80,
                      },
                      billboardColor: Cesium.Color.WHITE,
                      billboardFalseHoverColor:
                        Cesium.Color.WHITE.withAlpha(0.5),
                      labelFillColor: Cesium.Color.CHARTREUSE,
                      popupConfig: {
                        width: 492,
                        height: 420,
                      },
                      apiData: element,
                    },
                    billboard: false,
                    label: true,
                  });
                }
              });
              if (buildingArray && buildingArray.length > 0) {
                console.log("map-楼栋数据", buildingArray);
                entities_title_building = self.addBuildingTitle(
                  viewer,
                  buildingArray,
                  "building"
                );
              } else {
                entities_title_building = null;
                console.log("未获取到楼栋数据！");
              }
            } else {
              entities_title_building = null;
              self.$message.info("未获取楼栋数据！");
            }
          } else {
            self.$message.info("获取楼栋数据失败！");
          }

          // vue绑定数据
          setTimeout(() => {
            if (!CesiumGlobeData.vuePlot) {
              CesiumGlobeData.vuePlot = {};
              if (!CesiumGlobeData.vuePlot.title) {
                CesiumGlobeData.vuePlot.title = {};
              }
            }
            CesiumGlobeData.vuePlot.title.building = entities_title_building; // 楼栋mc
          }, 3000);
        })
        .catch(function (error) {
          console.error(error);
          // self.$message.error(error);
        });
    },
  
    addBillboardCluster(viewer, data, type) {
      let self = this;
      const layer =
        type == "septicTank"
          ? new ClusterLayer(viewer)
          : new ClusterLayer2(viewer);
      // layer._delegate.entities.removeAll();// 先清空
      data.forEach((element, index) => {
        // if (!element.position.lng || !element.position.lat) {
        //   return;
        // }
        let item = element.properties;
        layer._delegate.entities.add({
          id: "billboard_" + type + "_" + element.id, // 唯一性
          name: element.name,
          show:
            element.isShow == "show"
              ? true
              : element.isShow == "hide"
              ? false
              : element.isShow,
          position: Cesium.Cartesian3.fromDegrees(
            element.position.lng,
            element.position.lat,
            element.position.height
          ),
          properties: element.properties, // 与该实体关联的任意属性
          billboard: {
            id: "billboard_" + type + "_" + element.id, // 唯一性
            // 是否显示
            show: true,
            // 图像地址，URI或Canvas的属性
            image: require("../../assets/images/map/" + item.defaultImage.name),
            // 应用于图像的统一比例。比例大于会1.0放大标签，而比例小于会1.0缩小标签。
            scale: 1.0,
            // 该属性指定标签在屏幕空间中距此标签原点的像素偏移量
            pixelOffset: new Cesium.Cartesian2(0, 0),
            // 眼睛看到的偏移量
            eyeOffset: new Cesium.Cartesian3(0, 0, 0),
            // 相对于坐标的水平位置 CENTER、LEFT、RIGHT
            horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
            // 相对于坐标的垂直位置 CENTER、BOTTOM、BASELINE、TOP
            verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
            // 相对于坐标的高度 NONE、CLAMP_TO_GROUND、RELATIVE_TO_GROUND
            heightReference: Cesium.HeightReference.NONE,
            // 设置颜色和透明度
            color: item.billboardColor,
            // 旋转度
            rotation: 0,
            // 旋转轴
            alignedAxis: Cesium.Cartesian3.ZERO,
            // 大小是否以米为单位
            sizeInMeters: false,
            // 高度（以像素为单位）
            height: item.defaultImage.height,
            // 宽度（以像素为单位）
            width: item.defaultImage.width,
            // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              self.distanceDisplayCondition[0],
              self.distanceDisplayCondition[1]
            ),
            // 设置圆点深度检测阈值，解决Cesium billboard被3dtiles遮挡问题
            disableDepthTestDistance: Number.POSITIVE_INFINITY,
          },
        });
      });
      // console.log(layer._delegate);
      return layer._delegate.entities.values;
    },

    /**
     * 添加面、多边形
     */
    addPolygon(viewer, data, type) {
      let self = this;
      data.forEach((element, index) => {
        // if (
        //   !element.position.lng ||
        //   !element.position.lat ||
        //   !element.positions
        // ) {
        //   return;
        // }
        let entity = {
          id: "polygon_" + type + "_" + element.id, // 唯一性
          name: element.name,
          show:
            element.isShow == "show"
              ? true
              : element.isShow == "hide"
              ? false
              : element.isShow,
          position: Cesium.Cartesian3.fromDegrees(
            element.position.lng,
            element.position.lat,
            element.position.height
          ),
          properties: element.properties, // 与该实体关联的任意属性
        };
        if (element.polygon) {
          let item = element.properties;
          let polygon = {
            // 是否显示
            show: true,
            // 指定多边形层次结构，即多边形的经纬度
            // 包括有：positions，holes（图形内需要挖空的区域）
            hierarchy: {
              positions: Cesium.Cartesian3.fromDegreesArray(element.positions),
              holes: [
                {
                  positions: Cesium.Cartesian3.fromDegreesArray([]),
                },
              ],
            },
            // 距离地表高度，指定多边形相对于椭球表面的高度
            height: 0,
            // 相对height的高度 NONE、CLAMP_TO_GROUND、RELATIVE_TO_GROUND
            heightReference: Cesium.HeightReference.NONE,
            // 厚度，指定多边形的拉伸面相对于椭圆体表面的高度
            extrudedHeight: 0.2,
            // 相对厚度 NONE、CLAMP_TO_GROUND、RELATIVE_TO_GROUND
            extrudedHeightReference: Cesium.HeightReference.NONE,
            // 指定多边形纹理从北逆时针旋转的数值
            stRotation: 0.0,
            // 指定每个纬度和经度点之间的角度距离的数值
            granularity: Cesium.Math.RADIANS_PER_DEGREE,
            // 是否被提供的材质填充
            fill: true,
            // 填充的颜色，withAlpha透明度
            // material: item.defaultColor.material,
            material: new Cesium.ColorMaterialProperty(
              item.defaultColor.material
            ),
            // 边框
            outline: true,
            // 边框颜色
            outlineColor: item.defaultColor.outlineColor,
            // 边框尺寸
            outlineWidth: 5,
            // 是否利用每个点的高度,制造幅度
            perPositionHeight: false,
            // 是否关闭多边形的顶部,也就是拿掉盖子
            closeTop: true,
            // 是否关闭底部
            closeBottom: true,
            // 线条类型 NONE、GEODESIC、RHUMB
            arcType: Cesium.ArcType.GEODESIC,
            // 阴影 DISABLED、ENABLED、CAST_ONLY、RECEIVE_ONLY
            shadows: Cesium.ShadowMode.DISABLED,
            // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
            distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
              self.distanceDisplayCondition[0],
              self.distanceDisplayCondition[1]
            ),
            // 一个枚举属性，指定此多边形在地面上时是将地形、三维图块分类，还是两者都分类
            // TERRAIN、CESIUM_3D_TILE、BOTH
            classificationType: Cesium.ClassificationType.BOTH,
            // 遮盖顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
            zIndex: 1 + index,
          };
          entity.polygon = polygon;
        }
        viewer.entities.add(entity);
      });

      let entities = [];
      if (
        viewer.entities &&
        viewer.entities.values &&
        viewer.entities.values.length > 0
      ) {
        data.forEach((element) => {
          entities.push(
            self.getEntityById(viewer, "polygon", type, element.id)
          );
        });
      }
      return entities;
    },
    /**
     * 用于添加poi的icon和label的函数
     */
    poiIconLabelAdd(viewer, data) {
      let self = this;
      let name = data.xqmc;
      if (!data.jd || !data.wd) {
        return;
      }
      let lon = Number(data.jd);
      let lat = Number(data.wd);
      viewer.entities.add({
        isShow: true,
        id: "billboard_communityTop_" + data.id,
        name: name,
        position: Cesium.Cartesian3.fromDegrees(lon - 0.0001, lat, 200),
        properties: {
          defaultImage: {
            name: "building/header-icon.png",
            height: 55,
            width: 55,
          },
          activeImage: {
            name: "building/header-icon.png",
            height: 55,
            width: 55,
          },
          billboardColor: Cesium.Color.WHITE,
          billboardFalseHoverColor: Cesium.Color.WHITE.withAlpha(0.5),
          labelFillColor: Cesium.Color.TOMATO,
          popupConfig: {
            width: 1362,
            height: 676,
          },
          // 必须要有id、type、name
          apiData: {
            ...data,
            mc: data.xqmc,
          },
        }, // 与该实体关联的任意属性
        // 图标
        billboard: {
          image: require("../../assets/images/map/building/header-icon.png"),
          width: 55,
          height: 55,
          // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            self.distanceDisplayCondition2[0],
            self.distanceDisplayCondition2[1]
          ),
          // 设置圆点深度检测阈值，解决Cesium billboard被3dtiles遮挡问题
          disableDepthTestDistance: Number.POSITIVE_INFINITY,
        },
        label: {
          //文字标签
          text: name,
          font: "22px sans-serif",
          style: Cesium.LabelStyle.FILL_AND_OUTLINE,
          // 对齐方式(水平和竖直)
          horizontalOrigin: Cesium.HorizontalOrigin.LEFT,
          verticalOrigin: Cesium.VerticalOrigin.CENTER,
          pixelOffset: new Cesium.Cartesian2(20, -2),
          showBackground: true,
          backgroundColor: new Cesium.Color(10 / 255, 17 / 255, 47 / 255, 0.8),
          // 指定填充颜色
          // fillColor: item.labelFillColor,
          fillColor: Cesium.Color.WHITE.withAlpha(1),
          // 轮廓颜色
          outlineColor: Cesium.Color.WHITE.withAlpha(1),
          // 轮廓宽度
          outlineWidth: 2.0,
          // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            self.distanceDisplayCondition2[0],
            self.distanceDisplayCondition2[1]
          ),
        },
      });

      // 先画线后画点，防止线压盖点
      let linePositions = [];
      linePositions.push(new Cesium.Cartesian3.fromDegrees(lon, lat, 0));
      linePositions.push(
        new Cesium.Cartesian3.fromDegrees(lon - 0.0001, lat, 200)
      );
      viewer.entities.add({
        id: "polyline_communityMiddle_" + data.id,
        name: name,
        polyline: {
          positions: linePositions,
          width: 1.5,
          material: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
          // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            self.distanceDisplayCondition2[0] + 50,
            self.distanceDisplayCondition2[1] + 50
          ),
        },
      });

      // 画点
      viewer.entities.add({
        id: "point_communityBottom_" + data.id,
        name: name,
        // 给初始点位设置一定的离地高度，否者会被压盖
        position: Cesium.Cartesian3.fromDegrees(lon, lat, 5),
        point: {
          color: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
          pixelSize: 10,
          // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
          distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
            self.distanceDisplayCondition2[0] + 200,
            self.distanceDisplayCondition2[1] + 200
          ),
        },
      });

      CesiumGlobeData.communityTop = self.getEntityById(
        viewer,
        "communityTop",
        "billboard",
        data.id
      );
      CesiumGlobeData.communityMiddle = self.getEntityById(
        viewer,
        "communityMiddle",
        "polyline",
        data.id
      );
      CesiumGlobeData.communityBottom = self.getEntityById(
        viewer,
        "communityBottom",
        "dot",
        data.id
      );
    },

    /**
     * 显示或者隐藏相应的entity
     */
    isShowEntities(values, isShow, plotType, type) {
      if (values && values.length > 0) {
        values.forEach((element) => {
          if (
            element.id.indexOf(plotType) != -1 &&
            element.id.indexOf(type) != -1
          )
            element.show =
              isShow == "show" ? true : isShow == "hide" ? false : isShow;
        });
      }
    },
    /**
     * 隐藏或者显示某一类型标绘 entitry
     */
    isShowPlotTypeEntities(values, isShow, plotType) {
      let self = this;
      let values_septicTank_monitoring = [];
      if (
        self.isCluster &&
        plotType == "billboard" &&
        CesiumGlobeData.vuePlot &&
        CesiumGlobeData.vuePlot.billboard
      ) {
        let types = ["septicTank", "monitoring"];
        for (let index = 0; index < types.length; index++) {
          const type = types[index];
          var entitiesValues = CesiumGlobeData.vuePlot.billboard[type];
          entitiesValues.forEach((element) => {
            values_septicTank_monitoring.push(element);
          });
        }
      }
      var newValues = values_septicTank_monitoring.concat(values);
      if (newValues && newValues.length > 0) {
        newValues.forEach((element) => {
          if (element.id.indexOf(plotType) != -1) element.show = isShow;
        });
      }
    },
    /**
     * 激活某一个Entity
     * type和id为null时，取消激活
     */
    activetEntity(viewer, plotType, type, id) {
      // let self = this;
      // let entities = viewer.entities.values;
      let self = this;
      let entities =
        self.isCluster &&
        plotType == "billboard" &&
        (type == "septicTank" || type == "monitoring") &&
        CesiumGlobeData.vuePlot &&
        CesiumGlobeData.vuePlot.billboard
          ? CesiumGlobeData.vuePlot.billboard[type]
          : viewer.entities.values;
      // console.log(entities)
      let entitiesNew = [];
      entities.forEach((element) => {
        if (element.id.indexOf(plotType) != -1) {
          entitiesNew.push(element);
        }
      });
      if (entitiesNew && entitiesNew.length > 0 && plotType == "billboard") {
        if (id && type) {
          entitiesNew.forEach((entity) => {
            let dataID = entity.id.split(plotType + "_" + type + "_")[1];
            if (dataID == id && dataID !== undefined) {
              var activeImage = entity.properties.activeImage._value;
              // 设置激活图标
              entity.billboard.image = require("../../assets/images/map/" +
                activeImage.name);
              entity.billboard.width = activeImage.width;
              entity.billboard.height = activeImage.height;
              // 设置特效
              if (
                type == "fireHydrant" ||
                type == "gate" ||
                type == "antiepidemic" ||
                type == "monitoring" ||
                type == "septicTank"
              ) {
                self.createWallRegularDiffuse(
                  viewer,
                  entity.properties.apiData._value.jd,
                  entity.properties.apiData._value.wd,
                  entity.properties.apiData._value.id,
                  entity.properties.labelFillColor
                );
              }
              if (type == "entrance") {
                // var element = entity.properties.apiData._value;
                // self.addTempTitle(
                //   viewer,
                //   {
                //     id: element.id,
                //     name: element.mc,
                //     position: { lng: element.jd, lat: element.wd, height: 0 },
                //     properties: {
                //       defaultImage: entity.properties.defaultImage._value,
                //       activeImage: entity.properties.activeImage._value,
                //       billboardColor: entity.properties.billboardColor._value,
                //       billboardFalseHoverColor:
                //         entity.properties.billboardFalseHoverColor._value,
                //       labelFillColor: entity.properties.labelFillColor._value,
                //       popupConfig: entity.properties.popupConfig._value,
                //       apiData: entity.properties.apiData._value,
                //     },
                //     label: true,
                //   },
                //   type
                // );
                self.createRadarScan(
                  viewer,
                  {
                    id: entity.properties.apiData._value.id,
                    name: "雷达扫描",
                    position: {
                      lng: entity.properties.apiData._value.jd,
                      lat: entity.properties.apiData._value.wd,
                      height: 0,
                    },
                    maxAngle: 360,
                    radii: new Cesium.Cartesian3(12.0, 12.0, 2.0), // 扇形半径
                    innerRadii: new Cesium.Cartesian3(1.0, 1.0, 1.0), // 内半径
                  },
                  "specialEffects"
                );
              }
            } else {
              var defaultImage = entity.properties.defaultImage._value;
              // 还原默认图标
              entity.billboard.image = require("../../assets/images/map/" +
                defaultImage.name);
              entity.billboard.width = defaultImage.width;
              entity.billboard.height = defaultImage.height;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            var defaultImage = entity.properties.defaultImage._value;
            // 还原默认图标
            entity.billboard.image = require("../../assets/images/map/" +
              defaultImage.name);
            entity.billboard.width = defaultImage.width;
            entity.billboard.height = defaultImage.height;
          });
        }
      }
      if (entitiesNew && entitiesNew.length > 0 && plotType == "polygon") {
        if (id && type) {
          entitiesNew.forEach((entity) => {
            let dataID = entity.id.split(plotType + "_" + type + "_")[1];
            if (dataID == id && dataID !== undefined) {
              var activeColor = entity.properties.activeColor._value;
              // 设置激活颜色
              entity.polygon.material = activeColor.material;
              entity.polygon.outlineColor = activeColor.outlineColor;
            } else {
              var defaultColor = entity.properties.defaultColor._value;
              // 还原默认颜色
              entity.polygon.material = defaultColor.material;
              entity.polygon.outlineColor = defaultColor.outlineColor;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            var defaultColor = entity.properties.defaultColor._value;
            // 还原默认颜色
            entity.polygon.material = defaultColor.material;
            entity.polygon.outlineColor = defaultColor.outlineColor;
          });
        }
      }
    },
    /**
     * hover某一类型/系列、某一绘标的Entities
     * type为null时，取消hover
     * id为null时、不传时， hover某一类型/系列；id有值时， hover某一绘标
     * isShow，是否显示（仅plotType == "communityWall"、id == null时有效）
     */
    hoverEntities(viewer, plotType, type, id, isShow) {
      // let self = this;
      // let entities = viewer.entities.values;
      let self = this;
      let entities =
        self.isCluster &&
        plotType == "billboard" &&
        (type == "septicTank" || type == "monitoring") &&
        CesiumGlobeData.vuePlot &&
        CesiumGlobeData.vuePlot.billboard
          ? CesiumGlobeData.vuePlot.billboard[type]
          : viewer.entities.values;

      let entitiesNew = [];
      entities.forEach((element) => {
        if (element.id.indexOf(plotType) != -1) {
          entitiesNew.push(element);
        }
      });

      // 某一类型/系列 communityWall
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "communityWall" &&
        !id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1
            ) {
              // 显示该类型/系列的communityWall
              entity.show = isShow == undefined ? !entity.show : isShow;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 隐藏非该类型/系列的communityWall
            entity.show = false;
          });
        }
      }
      // 某一绘标 communityWall
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "communityWall" &&
        id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1 &&
              id == entity.id.split(plotType + "_" + type + "_")[1]
            ) {
              // 显示该绘标的communityWall
              entity.show = entity.show;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 隐藏该绘标的communityWall
            entity.show = false;
          });
        }
      }

      // 某一类型/系列 label
      if (entitiesNew && entitiesNew.length > 0 && plotType == "label" && !id) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1
            ) {
              // 显示该类型/系列的label
              /* entity.show = true;
              entity.label.show = true; */

              // 由于label过长，暂时不显示
              entity.show = false;
              entity.label.show = false;
            } else {
              // 隐藏非该类型/系列的label
              entity.show = false;
              entity.label.show = false;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 隐藏非该类型/系列的label
            entity.show = false;
            entity.label.show = false;
          });
        }
      }
      // 某一绘标 label
      if (entitiesNew && entitiesNew.length > 0 && plotType == "label" && id) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1 &&
              id == entity.id.split(plotType + "_" + type + "_")[1]
            ) {
              // 显示该绘标的label
              entity.show = true;
              entity.label.show = true;
              // 设置label的pixelOffset值为：- 当前图标的高度 - 8
              var billboard = self.getEntityById(
                viewer,
                "billboard",
                type,
                id
              ).billboard;
              entity.label.pixelOffset = new Cesium.Cartesian2(
                0,
                -billboard.height._value - 8
              );
            } else {
              // 隐藏该绘标的label
              entity.show = false;
              entity.label.show = false;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 隐藏该绘标的label
            entity.show = false;
            entity.label.show = false;
          });
        }
      }

      // 某一类型/系列 billboard
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "billboard" &&
        !id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            var billboardColor = entity.properties.billboardColor._value;
            var billboardFalseHoverColor =
              entity.properties.billboardFalseHoverColor._value;
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1
            ) {
              // 设置该类型/系列的hover的颜色和透明度
              entity.billboard.color = billboardColor;
            } else {
              // 设置非该类型/系列的hover的颜色和透明度
              entity.billboard.color = billboardFalseHoverColor;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            var billboardColor = entity.properties.billboardColor._value;
            // 还原默认的颜色和透明度
            entity.billboard.color = billboardColor;
          });
        }
      }
      // 某一绘标 billboard
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "billboard" &&
        id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            var billboardColor = entity.properties.billboardColor._value;
            var billboardFalseHoverColor =
              entity.properties.billboardFalseHoverColor._value;
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1 &&
              id == entity.id.split(plotType + "_" + type + "_")[1]
            ) {
              // 设置该绘标的hover的颜色和透明度
              entity.billboard.color = billboardColor;
            } else {
              // 设置非该绘标的hover的颜色和透明度
              entity.billboard.color = billboardFalseHoverColor;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            var billboardColor = entity.properties.billboardColor._value;
            // 还原默认的颜色和透明度
            entity.billboard.color = billboardColor;
          });
        }
      }

      // 某一类型/系列 polygon
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "polygon" &&
        !id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1
            ) {
              // 设置该类型/系列的hover的样式：变厚
              entity.polygon.extrudedHeight = 2.0;
              // entity.polygon.material = Cesium.Color.ORANGERED
            } else {
              // 设置非该类型/系列的hover的样式：不变厚
              entity.polygon.extrudedHeight = 0.2;
              // entity.polygon.material = Cesium.Color.BLUE;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 还原默认的的样式：还原厚度
            entity.polygon.extrudedHeight = 0.2;
            // entity.polygon.material = Cesium.Color.BLUE;
          });
        }
      }
      // 某一绘标 polygon
      if (
        entitiesNew &&
        entitiesNew.length > 0 &&
        plotType == "polygon" &&
        id
      ) {
        if (type) {
          entitiesNew.forEach((entity) => {
            if (
              entity.id.indexOf(plotType) != -1 &&
              entity.id.indexOf(type) != -1 &&
              id == entity.id.split(plotType + "_" + type + "_")[1]
            ) {
              // 设置该绘标的hover的样式：变厚
              // entity.polygon.extrudedHeight = 2.0;
              // entity.polygon.material = Cesium.Color.ORANGERED;
            } else {
              // 设置非该类绘标的hover的样式：不变厚
              // entity.polygon.extrudedHeight = 0.2;
              // entity.polygon.material = Cesium.Color.BLUE;
            }
          });
        } else {
          entitiesNew.forEach((entity) => {
            // 还原默认的样式：还原厚度
            // entity.polygon.extrudedHeight = 0.2;
            // entity.polygon.material = Cesium.Color.BLUE;
          });
        }
      }
    },
    /**
     * 点击显示或者隐藏某一类型/系列的Entities
     */
    clickEntities(viewer, plotType, type, isShow) {
      let self = this;
      let entities =
        self.isCluster &&
        plotType == "billboard" &&
        (type == "septicTank" || type == "monitoring") &&
        CesiumGlobeData.vuePlot &&
        CesiumGlobeData.vuePlot.billboard
          ? CesiumGlobeData.vuePlot.billboard[type]
          : viewer.entities.values;

      let entitiesNew = [];
      entities.forEach((element) => {
        if (
          element.id.indexOf(plotType) != -1 &&
          element.id.indexOf(type) != -1
        ) {
          entitiesNew.push(element);
        }
      });

      entitiesNew.forEach((entity) => {
        entity.show = isShow;
        // 显示或者隐藏该类型/系列的label
        if (plotType == "label") {
          entity.label.show = isShow;
        }
      });
    },
    /**
     * 点击显示或者隐藏某一Entity
     */
    clickEntity(viewer, plotType, type, id, isShow) {
      let self = this;
      let entity = self.getEntityById(viewer, plotType, type, id);
      if (!entity) {
        return;
      }
      entity.show = isShow;
      // 显示或者隐藏某一Entity的label
      if (plotType == "label") {
        entity.label.show = isShow;
      }
    },
    /**
     * 返回某一类型/系列的Entities
     */
    returnOneEntities(viewer, plotType, type) {
      let self = this;
      let entities = viewer.entities.values;

      let entitiesNew = [];
      entities.forEach((element) => {
        if (
          element.id.indexOf(plotType) != -1 &&
          element.id.indexOf(type) != -1
        ) {
          entitiesNew.push(element);
        }
      });

      return entitiesNew;
    },

    /**
     * 加载楼栋模型
     */
    loadModel(viewer, number, uri, position, floorHeigth, floor) {
      let self = this;
      const pt = Cesium.Cartesian3.fromDegrees(
        position.lng,
        position.lat,
        floorHeigth * (floor - 1)
      );
      console.log(floorHeigth * (floor - 1));
      const heading = Cesium.Math.toRadians(-40.0); // 方向
      const pitch = 0.0;
      const roll = 0.0;
      const hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);
      const orientation = Cesium.Transforms.headingPitchRollQuaternion(pt, hpr);
      let entity = {
        // isShow: true,
        id: "model_" + number + "_" + floor,
        name: floor,
        show: true,
        properties: {},
        // 设置方向
        orientation: orientation,
        // 设置位置
        position: pt,
        model: {
          // 是否显示
          show: true,
          // 引入模型
          uri: uri,
          // 应用于图像的统一比例。比例大于会1.0放大标签，而比例小于会1.0缩小标签。
          scale: 1.0,
          // 模型的近似最小像素大小，而不考虑缩放。这可以用来确保即使观看者缩小也可以看到模型。如果为0.0，则不强制使用最小大小
          minimumPixelSize: 1280 / 5,
          // 模型的最大比例大小
          maximumScale: 20000 / 5,
          // 增量加载纹理
          incrementallyLoadTextures: true,
          // 是否执行模型动画
          runAnimations: true,
          // 指定 glTF 动画是否应该在没有关键帧的情况下保持最后一个姿势
          clampAnimations: true,
          // 阴影 DISABLED、ENABLED、CAST_ONLY、RECEIVE_ONLY
          shadows: Cesium.ShadowMode.DISABLED,
          // 相对height的高度 NONE、CLAMP_TO_GROUND、RELATIVE_TO_GROUND
          heightReference: Cesium.HeightReference.NONE,
          // 设置模型轮廓（边框）颜色 rgba(0, 33, 112, 1)
          silhouetteColor: new Cesium.Color(0, 33 / 255, 112 / 255, 1),
          // 设置模型轮廓（边框）大小
          silhouetteSize: 0.0,
          // 模型的颜色（与模型的渲染颜色混合的属性） rgba(255, 255, 255, 1)
          color: new Cesium.Color(255 / 255, 255 / 255, 255 / 255, 1),
          // 指定颜色如何与模型混合 HIGHLIGHT、REPLACE、MIX
          colorBlendMode: Cesium.ColorBlendMode.HIGHLIGHT,
          // 当 colorBlendMode 为 MIX 时指定颜色强度
          colorBlendAmount: 0.5,
          // 指定基于漫反射和镜面反射图像的照明
          imageBasedLightingFactor: new Cesium.Cartesian2(2.0, 20.0),
          // 为模型着色时指定灯光颜色
          // lightColor: undefined,
          // 定义与相机的距离，显示在距相机的距离在多少区间内是可以显示的
          // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          //   self.distanceDisplayCondition[0],
          //   self.distanceDisplayCondition[1]
          // ),
        },
      };

      // viewer.entities.add(entity);

      // Cesium克隆帮你防止重复加载模型卡顿
      var entity_model = Cesium.clone(entity.model);
      viewer.entities.add({
        // isShow: true,
        id: "model_" + number + "_" + floor,
        name: floor,
        show: true,
        properties: {},
        // 设置方向
        orientation: orientation,
        // 设置位置
        position: pt,
        model: entity_model,
      });

      return self.getEntityById(viewer, "model", number, floor);
    },
    /**
     * 渲染楼栋的模型
     */
    renderBuildingModel(viewer, query, size) {
      let fixPosition = { lng: 108.350943, lat: 22.814786, height: 0 };
      let fixOffset = 0.000112 / 2; // 左移0.000112
      let self = this;
      // 隐藏标绘之前，临时记录它们的显示隐藏状态
      var plotStatus = {
        septicTank: self.$refs.cesiumMapLegend.judgeBillboard("septicTank")
          ? "show"
          : "hide",
        monitoring: self.$refs.cesiumMapLegend.judgeBillboard("monitoring")
          ? "show"
          : "hide",
        antiepidemic: self.$refs.cesiumMapLegend.judgeBillboard("antiepidemic")
          ? "show"
          : "hide",
        // community: self.$refs.cesiumMapLegend.judgeBillboard("community")?'show':'hide',
        gate: self.$refs.cesiumMapLegend.judgeBillboard("gate")
          ? "show"
          : "hide",
        fireHydrant: self.$refs.cesiumMapLegend.judgeBillboard("fireHydrant")
          ? "show"
          : "hide",
        entrance: self.$refs.cesiumMapLegend.judgeBillboard("entrance")
          ? "show"
          : "hide",
        communityWall: self.$refs.cesiumMapLegend.judgeWall("communityWall")
          ? "show"
          : "hide",
        grid: self.$refs.cesiumMapGridLegend.getCheckedCities(),
      };
      self.plotStatus = plotStatus;
      // 隐藏标绘- 图标、label、面、小区墙、线 communityMiddle 、点 communityBottom
      self.$refs.cesiumMapGridLegend.setCheckedCities([]); // 清空网格图例的checkbox
      self.isShowPlotTypeEntities(viewer.entities.values, false, "polygon");
      self.isShowPlotTypeEntities(viewer.entities.values, false, "billboard");
      self.isShowPlotTypeEntities(viewer.entities.values, false, "label");
      self.isShowPlotTypeEntities(viewer.entities.values, false, "title");
      self.isShowPlotTypeEntities(
        viewer.entities.values,
        false,
        "communityWall"
      );
      self.isShowPlotTypeEntities(viewer.entities.values, false, "polyline");
      self.isShowPlotTypeEntities(viewer.entities.values, false, "dot");
      // 创建楼栋定位点
      CesiumGlobeData.vueLocationPoint = self.createLocationPoint(
        viewer,
        // { lng: Number(query.lng) + fixOffset, lat: query.lat, height: 0 },
        { lng: fixPosition.lng + fixOffset, lat: fixPosition.lat, height: 0 },
        query.height,
        query.number
      );
      // 飞往该楼栋处 (通过楼栋定位点)
      self.viewerFlyTo(
        viewer,
        CesiumGlobeData.vueLocationPoint,
        {
          duration: self.buildingFlyOptions.duration,
          offset: {
            heading: Cesium.Math.toRadians(
              self.buildingFlyOptions.offset.heading
            ), // 方向
            pitch: Cesium.Math.toRadians(self.buildingFlyOptions.offset.pitch), // 倾斜角度
            range: self.buildingFlyOptions.offset.range,
          },
        },
        null
        // 15
      );
      // 隐藏地球
      viewer.scene.globe.show = false;
      self.isGlobe = false;
      // 如果为真，则允许用户旋转相机。如果为假，相机将锁定到当前标题。此标志仅适用于2D和3D。
      viewer.scene.screenSpaceCameraController.enableRotate = false;
      // 如果为true，则允许用户平移地图。如果为假，相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
      viewer.scene.screenSpaceCameraController.enableTranslate = false;
      // 如果为真，允许用户放大和缩小。如果为假，相机将锁定到距离椭圆体的当前距离
      viewer.scene.screenSpaceCameraController.enableZoom = false;
      // 如果为真，则允许用户倾斜相机。如果为假，相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
      viewer.scene.screenSpaceCameraController.enableTilt = false;
      // 清除原来的模型
      self.removeModel(viewer);

      let vueBuildingsModel = [];
      // 加载模型顶部
      if (true) {
        let index = query.floorTotal;
        var vueBuildingModel = self.loadModel(
          viewer,
          query.number + "-TOP",
          "static/model/buildings/" + query.number + "_Top.gltf", // 放置模型的文件名根据query.number命名
          // { lng: query.lng, lat: query.lat },
          { lng: fixPosition.lng, lat: fixPosition.lat },
          query.floorHeigth,
          index + 1
        );
        vueBuildingModel.model.silhouetteSize = size;
        vueBuildingModel.model.silhouetteColor = new Cesium.Color(
          self.silhouetteColor.r / 255,
          self.silhouetteColor.g / 255,
          self.silhouetteColor.b / 255,
          self.silhouetteColor.a
        );
        vueBuildingModel.model.color =
          index > 9
            ? new Cesium.Color(
                self.colors[9].r / 255,
                self.colors[9].g / 255,
                self.colors[9].b / 255,
                self.colors[9].a
              )
            : new Cesium.Color(
                self.colors[index].r / 255,
                self.colors[index].g / 255,
                self.colors[index].b / 255,
                self.colors[index].a
              );
        vueBuildingsModel.push(vueBuildingModel);
      }
      // 加载楼栋模型
      for (let index = 0; index < query.floorTotal; index++) {
        var vueBuildingModel = self.loadModel(
          viewer,
          query.number,
          "static/model/buildings/" + query.number + "_1st.gltf", // 放置模型的文件名根据query.number命名
          // { lng: query.lng, lat: query.lat },
          { lng: fixPosition.lng, lat: fixPosition.lat },
          query.floorHeigth,
          index + 1
        );
        vueBuildingModel.model.silhouetteSize = size;
        vueBuildingModel.model.silhouetteColor = new Cesium.Color(
          self.silhouetteColor.r / 255,
          self.silhouetteColor.g / 255,
          self.silhouetteColor.b / 255,
          self.silhouetteColor.a
        );
        vueBuildingModel.model.color =
          index > 9
            ? new Cesium.Color(
                self.colors[9].r / 255,
                self.colors[9].g / 255,
                self.colors[9].b / 255,
                self.colors[9].a
              )
            : new Cesium.Color(
                self.colors[index].r / 255,
                self.colors[index].g / 255,
                self.colors[index].b / 255,
                self.colors[index].a
              );
        vueBuildingsModel.push(vueBuildingModel);
      }
      CesiumGlobeData.vueBuildingsModel = vueBuildingsModel;
    },
    /**
     * 清除楼栋模型
     */
    removeModel(viewer) {
      let self = this;
      if (
        CesiumGlobeData.vueBuildingsModel &&
        CesiumGlobeData.vueBuildingsModel.length > 0
      ) {
        CesiumGlobeData.vueBuildingsModel.forEach((vueBuildingModel) => {
          viewer.entities.remove(vueBuildingModel);
        });
        CesiumGlobeData.vueBuildingsModel = null;
      }
    },
    /**
     * 移入楼栋时，先清除原先的提示线，使用entries创建提示线，显示，用于设置楼栋的提示线
     * positions [ 20.9677706, 30.7985748, 110.2, 34.55, ]
     */
    createBuildingTooltipLine(viewer, position, height, number) {
      let self = this;
      // 清除原来的楼栋提示线
      if (CesiumGlobeData.vueLocationPoint) {
        viewer.entities.remove(CesiumGlobeData.vueLocationPoint);
      }
      let entity = {
        id: "lineBuliding_" + "tooltip_" + number, // 唯一性
        show: true,
        polyline: {
          // fromDegrees返回给定的经度和纬度值数组（以度为单位），该数组由Cartesian3位置组成。
          positions: Cesium.Cartesian3.fromDegreesArray([
            position.lng,
            position.lat,
            height,
            position.lng,
            position.lat,
            height + 100,
          ]),
          // 宽度
          width: 2,
          // 线的颜色
          material: Cesium.Color.WHITE,
          // 线的顺序,仅当`clampToGround`为true并且支持地形上的折线时才有效。
          zIndex: 10,
          // 是否显示
          show: true,
        },
      };
      viewer.entities.add(entity);
      return self.getEntityById(viewer, "lineBuliding", "tooltip", number);
    },

    /**
     * 创建定位点
     */
    createLocationPoint(viewer, position, height, number) {
      let self = this;
      // 清除原来的定位点
      if (CesiumGlobeData.vueLocationPoint) {
        viewer.entities.remove(CesiumGlobeData.vueLocationPoint);
      }
      let entity = {
        id: "flyPoint_" + "location_" + number, // 唯一性
        show: true,
        // fromDegrees（经度，纬度，高度，椭球，结果）从以度为单位的经度和纬度值返回Cartesian3位置
        position: Cesium.Cartesian3.fromDegrees(
          position.lng,
          position.lat,
          height / 2
        ),
        point: {
          // 点的大小（像素）
          pixelSize: 0,
          // 点位颜色，fromCssColorString 可以直接使用CSS颜色
          color: Cesium.Color.fromCssColorString("#ee0000"),
          // 边框颜色
          outlineColor: Cesium.Color.fromCssColorString("#fff"),
          // 边框宽度(像素)
          outlineWidth: 0,
          // 是否显示
          show: true,
        },
      };
      viewer.entities.add(entity);
      return self.getEntityById(viewer, "flyPoint", "location", number);
    },

    /**
     * 自定义弹窗Popup（根据entity，适用于绘标plot）
     */
    openPopup(viewer, plotType, type, id, clusterArray, clusterIndex) {
      let self = this;
      let entity = self.getEntityById(viewer, "billboard", type, id);
      let gisPosition = entity.position._value;
      let popupConfig = entity.properties.popupConfig._value;
      let activeImage = entity.properties.activeImage._value;
      let apiData = entity.properties.apiData._value;
      let plotData = entity[plotType];
      self.mapPopupData = apiData;
      self.mapPopupData.name = apiData.mc;
      if (type == "gate") {
        let element = apiData;
        self.mapPopupData.name =
          element.wz +
          (element.lx
            ? "（" + ["", "单翼人闸", "双翼人闸", "车辆闸机"][element.lx] + "）"
            : "");
      } else if (type == "antiepidemic") {
        self.mapPopupData.name = apiData.wz;
      } else {
        self.mapPopupData.name = apiData.mc;
      }
      self.mapPopupData.type = type;
      self.mapPopupData.id = id;
      self.mapPopupData.clusterArray = clusterArray;
      self.mapPopupData.clusterIndex = clusterIndex;
      self.$refs.cesiumMapPopup.openOrClosePopup(true);
      // 实时更新位置
      viewer.scene.postRender.removeEventListener(realTimeUpdataPosition);
      viewer.scene.postRender.addEventListener(realTimeUpdataPosition);
      function realTimeUpdataPosition() {
        // 转化为屏幕坐标
        var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
          viewer.scene,
          gisPosition
        );
        self.mapPopupStyle.width = popupConfig.width + "px";
        self.mapPopupStyle.height = popupConfig.height + "px";
        if (windowPosition !== undefined) {
          self.mapPopupStyle.left =
            windowPosition.x - popupConfig.width / 2 + "px";
          if (type != "communityTop") {
            self.mapPopupStyle.top =
              windowPosition.y -
              popupConfig.height -
              activeImage.height -
              8 +
              "px"; // 164:popup高度 图标激活高度：68 popup与icon的间隔：8
          } else {
            self.mapPopupStyle.top = "150px";
          }
        }
        // 解决滚动不隐藏问题
        if (gisPosition) {
          const camerPosition = viewer.camera.position;
          let height =
            viewer.scene.globe.ellipsoid.cartesianToCartographic(
              camerPosition
            ).height;
          height += viewer.scene.globe.ellipsoid.maximumRadius;
          if (
            !(
              Cesium.Cartesian3.distance(camerPosition, gisPosition) > height
            ) &&
            viewer.camera.positionCartographic.height <
              (self.isCluster && (type == "septicTank" || type == "monitoring"))
              ? 12000
              : self.distanceDisplayCondition[1]
          ) {
            // self.$refs.cesiumMapPopup.openOrClosePopup(true);
          } else {
            type == "communityTop" ||
            (self.isCluster && (type == "septicTank" || type == "monitoring"))
              ? ""
              : self.$refs.cesiumMapPopup.openOrClosePopup(false);
          }
        }
      }
    },
    editClusterData(type, dataType) {
      if (this.mapPopupData.clusterArray) {
        let array = this.mapPopupData.clusterArray;
        let index = this.mapPopupData.clusterIndex;
        if (type == "+") {
          index++;
          if (index >= array.length) {
            index = array.length - 1;
            this.$message("已经是最后一条数据了");
            return;
          }
        }
        if (type == "-") {
          index--;
          if (index < 0) {
            index = 0;
            this.$message("已经是第一条数据了");
            return;
          }
        }
        let data = array[index];
        this.hoverEntities(window.vmCesiumViewer, "label", dataType, data.id);
        this.locationBillboard(dataType, data.id, true, array, index);
      }
    },
    /**
     * 自定义楼层信息窗
     */
    openFloorPopup(viewer, data) {
      let self = this;
      self.floorPopupData = data.apiData;
      self.$refs.floorPopup.openOrCloseFloorPopup(true);
      let h = self.$refs.floorPopup.$el.offsetHeight;
      let w = self.$refs.floorPopup.$el.offsetWidth;
      // console.log(h, w);
      // return;
      // 实时更新位置
      viewer.scene.postRender.removeEventListener(realTimeUpdataPosition2);
      viewer.scene.postRender.addEventListener(realTimeUpdataPosition2);
      function realTimeUpdataPosition2() {
        // 转化为屏幕坐标
        var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
          viewer.scene,
          data.gisPosition
        );

        if (windowPosition !== undefined) {
          self.floorPopupStyle.left = windowPosition.x - (w | 378) - 30 + "px";
          self.floorPopupStyle.top = windowPosition.y - (h | 355) - 30 + "px";
        } else {
          self.floorPopupStyle.left = "20%";
        }

        // 解决滚动不隐藏问题
        if (data.gisPosition) {
          const camerPosition = viewer.camera.position;
          let height =
            viewer.scene.globe.ellipsoid.cartesianToCartographic(
              camerPosition
            ).height;
          height += viewer.scene.globe.ellipsoid.maximumRadius;
          if (
            !(
              Cesium.Cartesian3.distance(camerPosition, data.gisPosition) >
              height
            ) &&
            viewer.camera.positionCartographic.height <
              self.distanceDisplayCondition[1]
          ) {
            // self.$refs.cesiumMapTooltip.openOrCloseFloorPopup(true);
          } else {
            // 暂时屏蔽
            // self.$refs.floorPopup.openOrCloseFloorPopup(false);
          }
        }
      }
    },
    /**
     * 自定义提示框Tooltip（根据data，适用于3DTileset等）
     */
    openTooltip(viewer, data, type, id) {
      let self = this;
      self.mapTooltipData = data.apiData;
      // self.mapTooltipData = {};
      self.mapTooltipData.name = data.apiData.name;
      self.mapTooltipData.type = type;
      self.mapTooltipData.id = id;
      self.$refs.cesiumMapTooltip.openOrCloseTooltip(true);
      let h = self.$refs.cesiumMapTooltip.$el.offsetHeight;
      let w = self.$refs.cesiumMapTooltip.$el.offsetWidth;
      // console.log(h, w)
      // 实时更新位置
      viewer.scene.postRender.removeEventListener(realTimeUpdataPosition3);
      viewer.scene.postRender.addEventListener(realTimeUpdataPosition3);
      function realTimeUpdataPosition3() {
        // 转化为屏幕坐标
        var windowPosition = Cesium.SceneTransforms.wgs84ToWindowCoordinates(
          viewer.scene,
          data.gisPosition
        );
        if (windowPosition !== undefined) {
          // 创建楼栋提示线
          // CesiumGlobeData.vueLocationPoint = self.createBuildingTooltipLine(
          //   viewer,
          //   { lng: data.apiData.position.lng, lat: data.apiData.position.lat },
          //   data.apiData.height,
          //   data.apiData.number
          // );
          self.mapTooltipStyle.left = windowPosition.x - (w || 100) / 2 + "px";
          self.mapTooltipStyle.top =
            windowPosition.y - (h || 36) - 0 - 54 + "px"; // 164:tooltip高度 tooltip与icon的间隔：18
        }
        // 解决滚动不隐藏问题
        if (data.gisPosition) {
          const camerPosition = viewer.camera.position;
          let height =
            viewer.scene.globe.ellipsoid.cartesianToCartographic(
              camerPosition
            ).height;
          height += viewer.scene.globe.ellipsoid.maximumRadius;
          if (
            !(
              Cesium.Cartesian3.distance(camerPosition, data.gisPosition) >
              height
            ) &&
            viewer.camera.positionCartographic.height <
              self.distanceDisplayCondition[1]
          ) {
            // self.$refs.cesiumMapTooltip.openOrCloseTooltip(true);
          } else {
            // 暂时屏蔽
            self.$refs.cesiumMapTooltip.openOrCloseTooltip(false);
          }
        }
      }
    },
    
    /**
     * 分类图元 \ 楼栋分层（通过面来分层）
     * https://cesium.com/learn/cesiumjs/ref-doc/PrimitiveCollection.html
     * https://cesium.com/learn/cesiumjs/ref-doc/ClassificationPrimitive.html
     * https://cesium.com/learn/cesiumjs/ref-doc/PolygonGeometry.html
     */
    createClassificationPrimitive(viewer, data, type) {
      let self = this;

      // self.isShowTileset(self.tilesetStyle == '新竹-科技风格' ? CesiumGlobeData.vueTileset1 : CesiumGlobeData.vueTileset2, false);

      self.removeClassificationPrimitives(viewer);

      data.forEach((element, index) => {
        let item = element.properties;
        // PolygonGeometry
        const polygonGeometry = new Cesium.PolygonGeometry({
          // 可以包含孔的多边形层次结构
          polygonHierarchy: new Cesium.PolygonHierarchy(
            Cesium.Cartesian3.fromDegreesArray(element.positions)
          ),
          // 距离地表高度，指定多边形相对于椭球表面的高度
          height: item.height,
          // 厚度，指定多边形的拉伸面相对于椭圆体表面的高度
          extrudedHeight: item.extrudedHeight,
          // 要计算的顶点属性
          // Cesium.VertexFormat.DEFAULT \ new Cesium.VertexFormat({ position : true, st : true })
          vertexFormat: Cesium.VertexFormat.DEFAULT,
          // 指定多边形纹理从北逆时针旋转的数值
          stRotation: 0.0,
          // 用作参考的椭球体
          ellipsoid: Cesium.Ellipsoid.WGS84,
          // 指定每个纬度和经度点之间的角度距离的数值
          granularity: Cesium.Math.RADIANS_PER_DEGREE,
          // 是否利用每个点的高度,制造幅度
          perPositionHeight: false,
          // 是否关闭多边形的顶部,也就是拿掉盖子
          closeTop: false,
          // 是否关闭底部
          closeBottom: false,
          // 线条类型 NONE、GEODESIC、RHUMB
          arcType: Cesium.ArcType.GEODESIC,
        });
        let primitivePolygon = new Cesium.ClassificationPrimitive({
          geometryInstances: new Cesium.GeometryInstance({
            geometry: Cesium.PolygonGeometry.createGeometry(polygonGeometry),
            attributes: {
              color: Cesium.ColorGeometryInstanceAttribute.fromColor(
                // 随机颜色 Cesium.Color.fromRandom({ alpha: 0.8 })
                item.defaultColor
              ),
              show: new Cesium.ShowGeometryInstanceAttribute(true),
            },
            // 设置id有效 其他属性无效
            id: "polygonClassificationPrimitive_" + type + "_" + element.id, // 唯一性（这里的type是楼栋编号、element.id是楼栋的第几层）
            // 以下是自定义的必要属性
            name: element.name,
            position: Cesium.Cartesian3.fromDegrees(
              element.position.lng,
              element.position.lat,
              element.position.height
            ),
            properties: element.properties,
          }),
          classificationType: Cesium.ClassificationType.CESIUM_3D_TILE,
        });
        if (element.PolygonGeometry) {
          // console.log(primitivePolygon)
          viewer.scene.primitives.add(primitivePolygon);
        }
      });

      let primitives = [];
      if (
        viewer.scene.primitives &&
        viewer.scene.primitives._primitives &&
        viewer.scene.primitives._primitives.length > 0
      ) {
        viewer.scene.primitives._primitives.forEach((element, index) => {
          if (element instanceof Cesium.ClassificationPrimitive) {
            primitives.push(element);
          }
        });
      }
      return primitives; // polygonClassificationPrimitives
    },
    removeClassificationPrimitives(viewer) {
      let self = this;
      // 如果原先已有polygonClassificationPrimitives，先删除
      if (
        CesiumGlobeData.vuePolygonClassificationPrimitives &&
        CesiumGlobeData.vuePolygonClassificationPrimitives.length > 0
      ) {
        CesiumGlobeData.vuePolygonClassificationPrimitives.forEach(
          (primitive) => {
            viewer.scene.primitives.remove(primitive);
          }
        );
      }
    },
  },
};
</script>
